include "bytedata.s7i";
const string: ELF_MAGIC is "\127;ELF";
const integer: ELF_IDENT_SIZE is 16;
const integer: ELF_HEADER32_SIZE is 52;
const integer: ELF_HEADER64_SIZE is 64;
const integer: ELF_PROGRAM_HEADER32_SIZE is 32;
const integer: ELF_PROGRAM_HEADER64_SIZE is 56;
const integer: ELF_SECTION_HEADER32_SIZE is 40;
const integer: ELF_SECTION_HEADER64_SIZE is 64;
const integer: ELF_NOTE_HEADER_SIZE is 12;
const integer: ELF_SYM32_SIZE is 16;
const integer: ELF_SYM64_SIZE is 24;
const integer: ELF_DYN32_SIZE is 8;
const integer: ELF_DYN64_SIZE is 16;
const integer: ELF_VER_D_AUX_SIZE is 8;
const integer: ELF_VER_N_AUX_SIZE is 16;
const integer: ELF_VER_NEED_SIZE is 16;
const integer: ELF_TARGET_OS_SYSTEM_V is 16#00;
const integer: ELF_TARGET_OS_HP_UX is 16#01;
const integer: ELF_TARGET_OS_NET_BSD is 16#02;
const integer: ELF_TARGET_OS_LINUX is 16#03;
const integer: ELF_TARGET_OS_GNU_HURD is 16#04;
const integer: ELF_TARGET_OS_SOLARIS is 16#06;
const integer: ELF_TARGET_OS_AIX is 16#07;
const integer: ELF_TARGET_OS_IRIX is 16#08;
const integer: ELF_TARGET_OS_FREE_BSD is 16#09;
const integer: ELF_TARGET_OS_TRU64 is 16#0a;
const integer: ELF_TARGET_OS_NOVELL_MODESTO is 16#0b;
const integer: ELF_TARGET_OS_OPEN_BSD is 16#0c;
const integer: ELF_TARGET_OS_OPEN_VMS is 16#0d;
const integer: ELF_TARGET_OS_NONSTOP_KERNEL is 16#0e;
const integer: ELF_TARGET_OS_AROS is 16#0f;
const integer: ELF_TARGET_OS_FENIX_OS is 16#10;
const integer: ELF_TARGET_OS_NUXI is 16#11;
const integer: ELF_TARGET_OS_OPEN_VOS is 16#12;
const integer: ELF_OBJECT_FILE_TYPE_NONE is 16#00;
const integer: ELF_OBJECT_FILE_TYPE_REL is 16#01;
const integer: ELF_OBJECT_FILE_TYPE_EXEC is 16#02;
const integer: ELF_OBJECT_FILE_TYPE_DYN is 16#03;
const integer: ELF_OBJECT_FILE_TYPE_CORE is 16#04;
const integer: ELF_OBJECT_FILE_TYPE_LOOS is 16#fE00;
const integer: ELF_OBJECT_FILE_TYPE_HIOS is 16#fEff;
const integer: ELF_OBJECT_FILE_TYPE_LOPROC is 16#ff00;
const integer: ELF_OBJECT_FILE_TYPE_HIPROC is 16#ffff;
const integer: ELF_MACHINE_NO_SPECIFIC is 16#00;
const integer: ELF_MACHINE_AT_AND_T_WE is 16#01;
const integer: ELF_MACHINE_SPARC is 16#02;
const integer: ELF_MACHINE_X86 is 16#03;
const integer: ELF_MACHINE_MOTOROLA_68000 is 16#04;
const integer: ELF_MACHINE_MOTOROLA_88000 is 16#05;
const integer: ELF_MACHINE_INTEL_MCU is 16#06;
const integer: ELF_MACHINE_INTEL_80860 is 16#07;
const integer: ELF_MACHINE_MIPS is 16#08;
const integer: ELF_MACHINE_IBM_SYSTEM_370 is 16#09;
const integer: ELF_MACHINE_MIPS_RS3000_LE is 16#0a;
const integer: ELF_MACHINE_HP_PA_RISC is 16#0f;
const integer: ELF_MACHINE_INTEL_80960 is 16#13;
const integer: ELF_MACHINE_POWER_PC is 16#14;
const integer: ELF_MACHINE_POWER_PC_64_BIT is 16#15;
const integer: ELF_MACHINE_S390 is 16#16;
const integer: ELF_MACHINE_IBM_SPU_SPC is 16#17;
const integer: ELF_MACHINE_NEC_V800 is 16#24;
const integer: ELF_MACHINE_FUJITSU_FR20 is 16#25;
const integer: ELF_MACHINE_TRW_RH_22 is 16#26;
const integer: ELF_MACHINE_MOTOROLA_RCE is 16#27;
const integer: ELF_MACHINE_ARM is 16#28;
const integer: ELF_MACHINE_DIGITAL_ALPHA is 16#29;
const integer: ELF_MACHINE_SUPER_H is 16#2a;
const integer: ELF_MACHINE_SPARC_VERSION_9 is 16#2b;
const integer: ELF_MACHINE_SIEMENS_TRI_CORE is 16#2c;
const integer: ELF_MACHINE_ARGONAUT_RISC is 16#2d;
const integer: ELF_MACHINE_HITACHI_H8_300 is 16#2e;
const integer: ELF_MACHINE_HITACHI_H8_300H is 16#2f;
const integer: ELF_MACHINE_HITACHI_H8S is 16#30;
const integer: ELF_MACHINE_HITACHI_H8_500 is 16#31;
const integer: ELF_MACHINE_IA_64 is 16#32;
const integer: ELF_MACHINE_STANFORD_MIPS_X is 16#33;
const integer: ELF_MACHINE_MOTOROLA_COLD_FIRE is 16#34;
const integer: ELF_MACHINE_MOTOROLA_M68HC12 is 16#35;
const integer: ELF_MACHINE_FUJITSU_MMA is 16#36;
const integer: ELF_MACHINE_SIEMENS_PCP is 16#37;
const integer: ELF_MACHINE_SONY_N_CPU is 16#38;
const integer: ELF_MACHINE_DENSO_NDR1 is 16#39;
const integer: ELF_MACHINE_MOTOROLA_STAR_CORE is 16#3a;
const integer: ELF_MACHINE_TOYOTA_ME16 is 16#3b;
const integer: ELF_MACHINE_ST100 is 16#3c;
const integer: ELF_MACHINE_TINY_J is 16#3d;
const integer: ELF_MACHINE_AMD_X86_64 is 16#3e;
const integer: ELF_MACHINE_SONY_DSP is 16#3f;
const integer: ELF_MACHINE_DEC_PDP_10 is 16#40;
const integer: ELF_MACHINE_DEC_PDP_11 is 16#41;
const integer: ELF_MACHINE_SIEMENS_FX66 is 16#42;
const integer: ELF_MACHINE_ST9 is 16#43;
const integer: ELF_MACHINE_ST7 is 16#44;
const integer: ELF_MACHINE_MOTOROLA_MC68HC16 is 16#45;
const integer: ELF_MACHINE_MOTOROLA_MC68HC11 is 16#46;
const integer: ELF_MACHINE_MOTOROLA_MC68HC08 is 16#47;
const integer: ELF_MACHINE_MOTOROLA_MC68HC05 is 16#48;
const integer: ELF_MACHINE_SILICON_GRAPHICS_SV_X is 16#49;
const integer: ELF_MACHINE_ST19 is 16#4a;
const integer: ELF_MACHINE_DIGITAL_VAX is 16#4b;
const integer: ELF_MACHINE_AXIS is 16#4c;
const integer: ELF_MACHINE_INFINEON is 16#4d;
const integer: ELF_MACHINE_ELEMENT_14 is 16#4e;
const integer: ELF_MACHINE_LSI_LOGIC is 16#4f;
const integer: ELF_MACHINE_TMS320C6000 is 16#8c;
const integer: ELF_MACHINE_MCST_ELBRUS_E2K is 16#af;
const integer: ELF_MACHINE_ARM_64 is 16#b7;
const integer: ELF_MACHINE_ZILOG_Z80 is 16#dc;
const integer: ELF_MACHINE_RISC_V is 16#f3;
const integer: ELF_MACHINE_BERKELEY_PACKET_FILTER is 16#f7;
const integer: ELF_MACHINE_WDC_65C816 is 16#101;
const integer: ELF_MACHINE_LOONG_ARCH is 16#102;
const integer: ELF_PT_NULL is 16#00000000;
const integer: ELF_PT_LOAD is 16#00000001;
const integer: ELF_PT_DYNAMIC is 16#00000002;
const integer: ELF_PT_INTERP is 16#00000003;
const integer: ELF_PT_NOTE is 16#00000004;
const integer: ELF_PT_SHLIB is 16#00000005;
const integer: ELF_PT_PHDR is 16#00000006;
const integer: ELF_PT_TLS is 16#00000007;
const integer: ELF_PT_LOOS is 16#60000000;
const integer: ELF_PT_HIOS is 16#6fffffff;
const integer: ELF_PT_LOPROC is 16#70000000;
const integer: ELF_PT_HIPROC is 16#7fffffff;
const integer: ELF_SHT_NULL is 16#0;
const integer: ELF_SHT_PROGBITS is 16#1;
const integer: ELF_SHT_SYMTAB is 16#2;
const integer: ELF_SHT_STRTAB is 16#3;
const integer: ELF_SHT_RELA is 16#4;
const integer: ELF_SHT_HASH is 16#5;
const integer: ELF_SHT_DYNAMIC is 16#6;
const integer: ELF_SHT_NOTE is 16#7;
const integer: ELF_SHT_NOBITS is 16#8;
const integer: ELF_SHT_REL is 16#9;
const integer: ELF_SHT_SHLIB is 16#a;
const integer: ELF_SHT_DYNSYM is 16#b;
const integer: ELF_SHT_INIT_ARRAY is 16#e;
const integer: ELF_SHT_FINI_ARRAY is 16#f;
const integer: ELF_SHT_PREINIT_ARRAY is 16#10;
const integer: ELF_SHT_GROUP is 16#11;
const integer: ELF_SHT_SYMTAB_SHNDX is 16#12;
const integer: ELF_SHT_NUM is 16#13;
const integer: ELF_SHT_LOOS is 16#60000000;
const integer: ELF_SHT_GNU_ATTRIBUTES is 16#6ffffff5;
const integer: ELF_SHT_GNU_HASH is 16#6ffffff6;
const integer: ELF_SHT_GNU_LIBLIST is 16#6ffffff7;
const integer: ELF_SHT_CHECKSUM is 16#6ffffff8;
const integer: ELF_SHT_LOSUNW is 16#6ffffffa;
const integer: ELF_SHT_SUNW_move is 16#6ffffffa;
const integer: ELF_SHT_SUNW_COMDAT is 16#6ffffffb;
const integer: ELF_SHT_SUNW_syminfo is 16#6ffffffc;
const integer: ELF_SHT_GNU_verdef is 16#6ffffffd;
const integer: ELF_SHT_GNU_verneed is 16#6ffffffe;
const integer: ELF_SHT_GNU_versym is 16#6fffffff;
const integer: ELF_SHF_WRITE is 16#1;
const integer: ELF_SHF_ALLOC is 16#2;
const integer: ELF_SHF_EXECINSTR is 16#4;
const integer: ELF_SHF_MERGE is 16#10;
const integer: ELF_SHF_STRINGS is 16#20;
const integer: ELF_SHF_INFO_LINK is 16#40;
const integer: ELF_SHF_LINK_ORDER is 16#80;
const integer: ELF_SHF_OS_NONCONFORMING is 16#100;
const integer: ELF_SHF_GROUP is 16#200;
const integer: ELF_SHF_TLS is 16#400;
const integer: ELF_SHF_MASKOS is 16#0ff00000;
const integer: ELF_SHF_MASKPROC is 16#f0000000;
const integer: ELF_SHF_ORDERED is 16#4000000;
const integer: ELF_SHF_EXCLUDE is 16#8000000;
const integer: ELF_DT_NULL is 0;
const integer: ELF_DT_NEEDED is 1;
const integer: ELF_DT_PLTRELSZ is 2;
const integer: ELF_DT_PLTGOT is 3;
const integer: ELF_DT_HASH is 4;
const integer: ELF_DT_STRTAB is 5;
const integer: ELF_DT_SYMTAB is 6;
const integer: ELF_DT_RELA is 7;
const integer: ELF_DT_RELASZ is 8;
const integer: ELF_DT_RELAENT is 9;
const integer: ELF_DT_STRSZ is 10;
const integer: ELF_DT_SYMENT is 11;
const integer: ELF_DT_INIT is 12;
const integer: ELF_DT_FINI is 13;
const integer: ELF_DT_SONAME is 14;
const integer: ELF_DT_RPATH is 15;
const integer: ELF_DT_SYMBOLIC is 16;
const integer: ELF_DT_REL is 17;
const integer: ELF_DT_RELSZ is 18;
const integer: ELF_DT_RELENT is 19;
const integer: ELF_DT_PLTREL is 20;
const integer: ELF_DT_DEBUG is 21;
const integer: ELF_DT_TEXTREL is 22;
const integer: ELF_DT_JMPREL is 23;
const integer: ELF_DT_BIND_NOW is 24;
const integer: ELF_DT_INIT_ARRAY is 25;
const integer: ELF_DT_FINI_ARRAY is 26;
const integer: ELF_DT_INIT_ARRAYSZ is 27;
const integer: ELF_DT_FINI_ARRAYSZ is 28;
const integer: ELF_DT_RUNPATH is 29;
const integer: ELF_DT_FLAGS is 30;
const integer: ELF_DT_ENCODING is 32;
const integer: ELF_DT_PREINIT_ARRAY is 32;
const integer: ELF_DT_PREINIT_ARRAYSZ is 33;
const integer: ELF_DT_SYMTAB_SHNDX is 34;
const integer: ELF_DT_RELRSZ is 35;
const integer: ELF_DT_RELR is 36;
const integer: ELF_DT_RELRENT is 37;
const integer: ELF_DT_NUM is 38;
const type: elfHeader is new struct
var string: magic is "";
var integer: addressSize is 0;
var boolean: isLittleEndian is TRUE;
var integer: elfVersion is 0;
var integer: targetOs is 0;
var integer: abiVersion is 0;
var integer: objectFileType is 0;
var integer: machine is 0;
var integer: version is 0;
var integer: entry is 0;
var integer: programHeaderOffset is 0;
var integer: sectionHeaderOffset is 0;
var integer: flags is 0;
var integer: headerSize is 0;
var integer: programHeaderSize is 0;
var integer: programHeaderNum is 0;
var integer: sectionHeaderSize is 0;
var integer: sectionHeaderNum is 0;
var integer: nameSectionIndex is 0;
end struct;
const proc: show (in elfHeader: header) is func
begin
writeln("magic: " <& literal(header.magic));
writeln("addressSize: " <& header.addressSize);
writeln("isLittleEndian: " <& header.isLittleEndian);
writeln("elfVersion: " <& header.elfVersion);
writeln("targetOs: " <& header.targetOs);
writeln("abiVersion: " <& header.abiVersion);
writeln("objectFileType: " <& header.objectFileType);
writeln("machine: 16#" <& header.machine radix 16);
writeln("version: " <& header.version);
writeln("entry: " <& header.entry);
writeln("programHeaderOffset: " <& header.programHeaderOffset);
writeln("sectionHeaderOffset: " <& header.sectionHeaderOffset);
writeln("flags: " <& header.flags);
writeln("headerSize: " <& header.headerSize);
writeln("programHeaderSize: " <& header.programHeaderSize);
writeln("programHeaderNum: " <& header.programHeaderNum);
writeln("sectionHeaderSize: " <& header.sectionHeaderSize);
writeln("sectionHeaderNum: " <& header.sectionHeaderNum);
writeln("nameSectionIndex: " <& header.nameSectionIndex);
end func;
const proc: readHeader32Le (in string: stri, inout elfHeader: header) is func
begin
header.objectFileType := bytes2Int(stri[17 fixLen 2], UNSIGNED, LE);
header.machine := bytes2Int(stri[19 fixLen 2], UNSIGNED, LE);
header.version := bytes2Int(stri[21 fixLen 4], UNSIGNED, LE);
header.entry := bytes2Int(stri[25 fixLen 4], UNSIGNED, LE);
header.programHeaderOffset := bytes2Int(stri[29 fixLen 4], UNSIGNED, LE);
header.sectionHeaderOffset := bytes2Int(stri[33 fixLen 4], UNSIGNED, LE);
header.flags := bytes2Int(stri[37 fixLen 4], UNSIGNED, LE);
header.headerSize := bytes2Int(stri[41 fixLen 2], UNSIGNED, LE);
header.programHeaderSize := bytes2Int(stri[43 fixLen 2], UNSIGNED, LE);
header.programHeaderNum := bytes2Int(stri[45 fixLen 2], UNSIGNED, LE);
header.sectionHeaderSize := bytes2Int(stri[47 fixLen 2], UNSIGNED, LE);
header.sectionHeaderNum := bytes2Int(stri[49 fixLen 2], UNSIGNED, LE);
header.nameSectionIndex := bytes2Int(stri[51 fixLen 2], UNSIGNED, LE);
end func;
const proc: readHeader32Be (in string: stri, inout elfHeader: header) is func
begin
header.objectFileType := bytes2Int(stri[17 fixLen 2], UNSIGNED, BE);
header.machine := bytes2Int(stri[19 fixLen 2], UNSIGNED, BE);
header.version := bytes2Int(stri[21 fixLen 4], UNSIGNED, BE);
header.entry := bytes2Int(stri[25 fixLen 4], UNSIGNED, BE);
header.programHeaderOffset := bytes2Int(stri[29 fixLen 4], UNSIGNED, BE);
header.sectionHeaderOffset := bytes2Int(stri[33 fixLen 4], UNSIGNED, BE);
header.flags := bytes2Int(stri[37 fixLen 4], UNSIGNED, BE);
header.headerSize := bytes2Int(stri[41 fixLen 2], UNSIGNED, BE);
header.programHeaderSize := bytes2Int(stri[43 fixLen 2], UNSIGNED, BE);
header.programHeaderNum := bytes2Int(stri[45 fixLen 2], UNSIGNED, BE);
header.sectionHeaderSize := bytes2Int(stri[47 fixLen 2], UNSIGNED, BE);
header.sectionHeaderNum := bytes2Int(stri[49 fixLen 2], UNSIGNED, BE);
header.nameSectionIndex := bytes2Int(stri[51 fixLen 2], UNSIGNED, BE);
end func;
const proc: readHeader64Le (in string: stri, inout elfHeader: header) is func
begin
header.objectFileType := bytes2Int(stri[17 fixLen 2], UNSIGNED, LE);
header.machine := bytes2Int(stri[19 fixLen 2], UNSIGNED, LE);
header.version := bytes2Int(stri[21 fixLen 4], UNSIGNED, LE);
header.entry := bytes2Int(stri[25 fixLen 8], UNSIGNED, LE);
header.programHeaderOffset := bytes2Int(stri[33 fixLen 8], UNSIGNED, LE);
header.sectionHeaderOffset := bytes2Int(stri[41 fixLen 8], UNSIGNED, LE);
header.flags := bytes2Int(stri[49 fixLen 4], UNSIGNED, LE);
header.headerSize := bytes2Int(stri[53 fixLen 2], UNSIGNED, LE);
header.programHeaderSize := bytes2Int(stri[55 fixLen 2], UNSIGNED, LE);
header.programHeaderNum := bytes2Int(stri[57 fixLen 2], UNSIGNED, LE);
header.sectionHeaderSize := bytes2Int(stri[59 fixLen 2], UNSIGNED, LE);
header.sectionHeaderNum := bytes2Int(stri[61 fixLen 2], UNSIGNED, LE);
header.nameSectionIndex := bytes2Int(stri[63 fixLen 2], UNSIGNED, LE);
end func;
const proc: readHeader64Be (in string: stri, inout elfHeader: header) is func
begin
header.objectFileType := bytes2Int(stri[17 fixLen 2], UNSIGNED, BE);
header.machine := bytes2Int(stri[19 fixLen 2], UNSIGNED, BE);
header.version := bytes2Int(stri[21 fixLen 4], UNSIGNED, BE);
header.entry := bytes2Int(stri[25 fixLen 8], UNSIGNED, BE);
header.programHeaderOffset := bytes2Int(stri[33 fixLen 8], UNSIGNED, BE);
header.sectionHeaderOffset := bytes2Int(stri[41 fixLen 8], UNSIGNED, BE);
header.flags := bytes2Int(stri[49 fixLen 4], UNSIGNED, BE);
header.headerSize := bytes2Int(stri[53 fixLen 2], UNSIGNED, BE);
header.programHeaderSize := bytes2Int(stri[55 fixLen 2], UNSIGNED, BE);
header.programHeaderNum := bytes2Int(stri[57 fixLen 2], UNSIGNED, BE);
header.sectionHeaderSize := bytes2Int(stri[59 fixLen 2], UNSIGNED, BE);
header.sectionHeaderNum := bytes2Int(stri[61 fixLen 2], UNSIGNED, BE);
header.nameSectionIndex := bytes2Int(stri[63 fixLen 2], UNSIGNED, BE);
end func;
const proc: readHeader (inout file: inFile, inout elfHeader: header) is func
local
var string: stri is "";
var integer: addressFormat is 0;
var integer: endianess is 0;
begin
stri := gets(inFile, ELF_IDENT_SIZE);
if length(stri) = ELF_IDENT_SIZE then
header.magic := stri[ 1 fixLen 4];
addressFormat := bytes2Int(stri[ 5 fixLen 1], UNSIGNED, LE);
endianess := bytes2Int(stri[ 6 fixLen 1], UNSIGNED, LE);
header.elfVersion := bytes2Int(stri[ 7 fixLen 1], UNSIGNED, LE);
header.targetOs := bytes2Int(stri[ 8 fixLen 1], UNSIGNED, LE);
header.abiVersion := bytes2Int(stri[ 9 fixLen 1], UNSIGNED, LE);
if header.magic = ELF_MAGIC then
if addressFormat = 1 then
stri &:= gets(inFile, ELF_HEADER32_SIZE - ELF_IDENT_SIZE);
if length(stri) = ELF_HEADER32_SIZE then
header.addressSize := 32;
if endianess = 1 then
header.isLittleEndian := TRUE;
readHeader32Le(stri, header);
elsif endianess = 2 then
header.isLittleEndian := FALSE;
readHeader32Be(stri, header);
else
raise RANGE_ERROR;
end if;
else
raise RANGE_ERROR;
end if;
elsif addressFormat = 2 then
stri &:= gets(inFile, ELF_HEADER64_SIZE - ELF_IDENT_SIZE);
if length(stri) = ELF_HEADER64_SIZE then
header.addressSize := 64;
if endianess = 1 then
header.isLittleEndian := TRUE;
readHeader64Le(stri, header);
elsif endianess = 2 then
header.isLittleEndian := FALSE;
readHeader64Be(stri, header);
else
raise RANGE_ERROR;
end if;
else
raise RANGE_ERROR;
end if;
else
raise RANGE_ERROR;
end if;
end if;
end if;
end func;
const type: elfProgramHeader is new struct
var integer: segmentType is 0;
var integer: offset is 0;
var integer: virtualAddr is 0;
var integer: physicalAddr is 0;
var integer: fileSize is 0;
var integer: memorySize is 0;
var integer: flags is 0;
var integer: alignment is 0;
var integer: addressSize is 0;
var boolean: isLittleEndian is TRUE;
end struct;
const proc: show (in elfProgramHeader: header) is func
begin
writeln("segmentType: " <& header.segmentType);
writeln("flags: " <& header.flags);
writeln("offset: " <& header.offset);
writeln("virtualAddr: " <& header.virtualAddr);
writeln("physicalAddr: " <& header.physicalAddr);
writeln("fileSize: " <& header.fileSize);
writeln("memorySize: " <& header.memorySize);
writeln("alignment: " <& header.alignment);
writeln("addressSize: " <& header.addressSize);
writeln("isLittleEndian: " <& header.isLittleEndian);
end func;
const proc: readProgramHeader32Le (in string: stri,
inout elfProgramHeader: programHeader) is func
begin
programHeader.segmentType := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
programHeader.offset := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
programHeader.virtualAddr := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
programHeader.physicalAddr := bytes2Int(stri[13 fixLen 4], UNSIGNED, LE);
programHeader.fileSize := bytes2Int(stri[17 fixLen 4], UNSIGNED, LE);
programHeader.memorySize := bytes2Int(stri[21 fixLen 4], UNSIGNED, LE);
programHeader.flags := bytes2Int(stri[25 fixLen 4], UNSIGNED, LE);
programHeader.alignment := bytes2Int(stri[29 fixLen 4], UNSIGNED, LE);
end func;
const proc: readProgramHeader32Be (in string: stri,
inout elfProgramHeader: programHeader) is func
begin
programHeader.segmentType := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
programHeader.offset := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
programHeader.virtualAddr := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
programHeader.physicalAddr := bytes2Int(stri[13 fixLen 4], UNSIGNED, BE);
programHeader.fileSize := bytes2Int(stri[17 fixLen 4], UNSIGNED, BE);
programHeader.memorySize := bytes2Int(stri[21 fixLen 4], UNSIGNED, BE);
programHeader.flags := bytes2Int(stri[25 fixLen 4], UNSIGNED, BE);
programHeader.alignment := bytes2Int(stri[29 fixLen 4], UNSIGNED, BE);
end func;
const proc: readProgramHeader64Le (in string: stri,
inout elfProgramHeader: programHeader) is func
begin
programHeader.segmentType := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
programHeader.flags := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
programHeader.offset := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, LE);
programHeader.virtualAddr := bytes2Int(stri[17 fixLen 8], UNSIGNED, LE);
programHeader.physicalAddr := bytes2Int(stri[25 fixLen 8], UNSIGNED, LE);
programHeader.fileSize := bytes2Int(stri[33 fixLen 8], UNSIGNED, LE);
programHeader.memorySize := bytes2Int(stri[41 fixLen 8], UNSIGNED, LE);
programHeader.alignment := bytes2Int(stri[49 fixLen 8], UNSIGNED, LE);
end func;
const proc: readProgramHeader64Be (in string: stri,
inout elfProgramHeader: programHeader) is func
begin
programHeader.segmentType := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
programHeader.flags := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
programHeader.offset := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, BE);
programHeader.virtualAddr := bytes2Int(stri[17 fixLen 8], UNSIGNED, BE);
programHeader.physicalAddr := bytes2Int(stri[25 fixLen 8], UNSIGNED, BE);
programHeader.fileSize := bytes2Int(stri[33 fixLen 8], UNSIGNED, BE);
programHeader.memorySize := bytes2Int(stri[41 fixLen 8], UNSIGNED, BE);
programHeader.alignment := bytes2Int(stri[49 fixLen 8], UNSIGNED, BE);
end func;
const proc: readProgramHeader (inout file: inFile, in elfHeader: header,
inout elfProgramHeader: programHeader) is func
local
var string: stri is "";
begin
stri := gets(inFile, header.programHeaderSize);
if length(stri) = header.programHeaderSize then
if header.addressSize = 32 then
if length(stri) >= ELF_PROGRAM_HEADER32_SIZE then
if header.isLittleEndian then
readProgramHeader32Le(stri, programHeader);
else
readProgramHeader32Be(stri, programHeader);
end if;
else
raise RANGE_ERROR;
end if;
elsif header.addressSize = 64 then
if length(stri) >= ELF_PROGRAM_HEADER64_SIZE then
if header.isLittleEndian then
readProgramHeader64Le(stri, programHeader);
else
readProgramHeader64Be(stri, programHeader);
end if;
else
raise RANGE_ERROR;
end if;
end if;
programHeader.addressSize := header.addressSize;
programHeader.isLittleEndian := header.isLittleEndian;
else
raise RANGE_ERROR;
end if;
end func;
const type: elfSectionHeader is new struct
var integer: nameOffset is 0;
var integer: sectionType is 0;
var integer: flags is 0;
var integer: address is 0;
var integer: offset is 0;
var integer: size is 0;
var integer: link is 0;
var integer: info is 0;
var integer: addrAlignment is 0;
var integer: entrySize is 0;
var string: name is "";
var integer: addressSize is 0;
var boolean: isLittleEndian is TRUE;
end struct;
const func string: sectionTypeName (in integer: sectionType) is func
result
var string: typeName is "";
begin
case sectionType of
when {ELF_SHT_NULL}: typeName := "SHT_NULL";
when {ELF_SHT_PROGBITS}: typeName := "SHT_PROGBITS";
when {ELF_SHT_SYMTAB}: typeName := "SHT_SYMTAB";
when {ELF_SHT_STRTAB}: typeName := "SHT_STRTAB";
when {ELF_SHT_RELA}: typeName := "SHT_RELA";
when {ELF_SHT_HASH}: typeName := "SHT_HASH";
when {ELF_SHT_DYNAMIC}: typeName := "SHT_DYNAMIC";
when {ELF_SHT_NOTE}: typeName := "SHT_NOTE";
when {ELF_SHT_NOBITS}: typeName := "SHT_NOBITS";
when {ELF_SHT_REL}: typeName := "SHT_REL";
when {ELF_SHT_SHLIB}: typeName := "SHT_SHLIB";
when {ELF_SHT_DYNSYM}: typeName := "SHT_DYNSYM";
when {ELF_SHT_INIT_ARRAY}: typeName := "SHT_INIT_ARRAY";
when {ELF_SHT_FINI_ARRAY}: typeName := "SHT_FINI_ARRAY";
when {ELF_SHT_PREINIT_ARRAY}: typeName := "SHT_PREINIT_ARRAY";
when {ELF_SHT_GROUP}: typeName := "SHT_GROUP";
when {ELF_SHT_SYMTAB_SHNDX}: typeName := "SHT_SYMTAB_SHNDX";
when {ELF_SHT_NUM}: typeName := "SHT_NUM";
when {ELF_SHT_GNU_ATTRIBUTES}: typeName := "SHT_GNU_ATTRIBUTES";
when {ELF_SHT_GNU_HASH}: typeName := "SHT_GNU_HASH";
when {ELF_SHT_GNU_LIBLIST}: typeName := "SHT_GNU_LIBLIST";
when {ELF_SHT_CHECKSUM}: typeName := "SHT_CHECKSUM";
when {ELF_SHT_SUNW_move}: typeName := "SHT_SUNW_move";
when {ELF_SHT_SUNW_COMDAT}: typeName := "SHT_SUNW_COMDAT";
when {ELF_SHT_SUNW_syminfo}: typeName := "SHT_SUNW_syminfo";
when {ELF_SHT_GNU_verdef}: typeName := "SHT_GNU_verdef";
when {ELF_SHT_GNU_verneed}: typeName := "SHT_GNU_verneed";
when {ELF_SHT_GNU_versym}: typeName := "SHT_GNU_versym";
otherwise: typeName := sectionType radix 16;
end case;
end func;
const proc: show (in elfSectionHeader: header) is func
begin
writeln("nameOffset: " <& header.nameOffset);
writeln("sectionType: " <& header.sectionType <& " " <& sectionTypeName(header.sectionType));
writeln("flags: " <& header.flags);
writeln("address: " <& header.address);
writeln("offset: " <& header.offset);
writeln("size: " <& header.size);
writeln("link: " <& header.link);
writeln("info: " <& header.info);
writeln("addrAlignment: " <& header.addrAlignment);
writeln("entrySize: " <& header.entrySize);
writeln("name: " <& header.name);
writeln("addressSize: " <& header.addressSize);
writeln("isLittleEndian: " <& header.isLittleEndian);
end func;
const proc: readSectionHeader32Le (in string: stri,
inout elfSectionHeader: sectionHeader) is func
begin
sectionHeader.nameOffset := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
sectionHeader.sectionType := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
sectionHeader.flags := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
sectionHeader.address := bytes2Int(stri[13 fixLen 4], UNSIGNED, LE);
sectionHeader.offset := bytes2Int(stri[17 fixLen 4], UNSIGNED, LE);
sectionHeader.size := bytes2Int(stri[21 fixLen 4], UNSIGNED, LE);
sectionHeader.link := bytes2Int(stri[25 fixLen 4], UNSIGNED, LE);
sectionHeader.info := bytes2Int(stri[29 fixLen 4], UNSIGNED, LE);
sectionHeader.addrAlignment := bytes2Int(stri[33 fixLen 4], UNSIGNED, LE);
sectionHeader.entrySize := bytes2Int(stri[37 fixLen 4], UNSIGNED, LE);
end func;
const proc: readSectionHeader32Be (in string: stri,
inout elfSectionHeader: sectionHeader) is func
begin
sectionHeader.nameOffset := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
sectionHeader.sectionType := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
sectionHeader.flags := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
sectionHeader.address := bytes2Int(stri[13 fixLen 4], UNSIGNED, BE);
sectionHeader.offset := bytes2Int(stri[17 fixLen 4], UNSIGNED, BE);
sectionHeader.size := bytes2Int(stri[21 fixLen 4], UNSIGNED, BE);
sectionHeader.link := bytes2Int(stri[25 fixLen 4], UNSIGNED, BE);
sectionHeader.info := bytes2Int(stri[29 fixLen 4], UNSIGNED, BE);
sectionHeader.addrAlignment := bytes2Int(stri[33 fixLen 4], UNSIGNED, BE);
sectionHeader.entrySize := bytes2Int(stri[37 fixLen 4], UNSIGNED, BE);
end func;
const proc: readSectionHeader64Le (in string: stri,
inout elfSectionHeader: sectionHeader) is func
begin
sectionHeader.nameOffset := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
sectionHeader.sectionType := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
sectionHeader.flags := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, LE);
sectionHeader.address := bytes2Int(stri[17 fixLen 8], UNSIGNED, LE);
sectionHeader.offset := bytes2Int(stri[25 fixLen 8], UNSIGNED, LE);
sectionHeader.size := bytes2Int(stri[33 fixLen 8], UNSIGNED, LE);
sectionHeader.link := bytes2Int(stri[41 fixLen 4], UNSIGNED, LE);
sectionHeader.info := bytes2Int(stri[45 fixLen 4], UNSIGNED, LE);
sectionHeader.addrAlignment := bytes2Int(stri[49 fixLen 8], UNSIGNED, LE);
sectionHeader.entrySize := bytes2Int(stri[57 fixLen 8], UNSIGNED, LE);
end func;
const proc: readSectionHeader64Be (in string: stri,
inout elfSectionHeader: sectionHeader) is func
begin
sectionHeader.nameOffset := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
sectionHeader.sectionType := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
sectionHeader.flags := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, BE);
sectionHeader.address := bytes2Int(stri[17 fixLen 8], UNSIGNED, BE);
sectionHeader.offset := bytes2Int(stri[25 fixLen 8], UNSIGNED, BE);
sectionHeader.size := bytes2Int(stri[33 fixLen 8], UNSIGNED, BE);
sectionHeader.link := bytes2Int(stri[41 fixLen 4], UNSIGNED, BE);
sectionHeader.info := bytes2Int(stri[45 fixLen 4], UNSIGNED, BE);
sectionHeader.addrAlignment := bytes2Int(stri[49 fixLen 8], UNSIGNED, BE);
sectionHeader.entrySize := bytes2Int(stri[57 fixLen 8], UNSIGNED, BE);
end func;
const proc: readSectionHeader (inout file: inFile, in elfHeader: header,
inout elfSectionHeader: sectionHeader) is func
local
var string: stri is "";
begin
stri := gets(inFile, header.sectionHeaderSize);
if length(stri) = header.sectionHeaderSize then
if header.addressSize = 32 then
if length(stri) >= ELF_SECTION_HEADER32_SIZE then
if header.isLittleEndian then
readSectionHeader32Le(stri, sectionHeader);
else
readSectionHeader32Be(stri, sectionHeader);
end if;
else
raise RANGE_ERROR;
end if;
elsif header.addressSize = 64 then
if length(stri) >= ELF_SECTION_HEADER64_SIZE then
if header.isLittleEndian then
readSectionHeader64Le(stri, sectionHeader);
else
readSectionHeader64Be(stri, sectionHeader);
end if;
else
raise RANGE_ERROR;
end if;
end if;
sectionHeader.addressSize := header.addressSize;
sectionHeader.isLittleEndian := header.isLittleEndian;
else
raise RANGE_ERROR;
end if;
end func;
const type: elfSectionNameHash is hash [string] integer;
const type: elfData is sub emptyFileSys struct
var file: elfFile is STD_NULL;
var elfHeader: header is elfHeader.value;
var array elfProgramHeader: programHeaders is 0 times elfProgramHeader.value;
var array elfSectionHeader: sectionHeaders is 0 times elfSectionHeader.value;
var string: sectionNameTable is "";
var elfSectionNameHash: sectionNameHash is elfSectionNameHash.value;
end struct;
const func elfData: openElf (inout file: elfFile) is func
result
var elfData: data is elfData.value;
local
var elfSectionHeader: sectionHeader0 is elfSectionHeader.value;
var integer: index is 0;
begin
readHeader(elfFile, data.header);
if data.header.magic = ELF_MAGIC then
if data.header.sectionHeaderNum = 0 and
data.header.sectionHeaderOffset <> 0 then
seek(elfFile, succ(data.header.sectionHeaderOffset));
readSectionHeader(elfFile, data.header, sectionHeader0);
data.header.sectionHeaderNum := sectionHeader0.size;
end if;
data.elfFile := elfFile;
data.programHeaders := data.header.programHeaderNum times elfProgramHeader.value;
seek(elfFile, succ(data.header.programHeaderOffset));
for index range 1 to data.header.programHeaderNum do
readProgramHeader(elfFile, data.header, data.programHeaders[index]);
end for;
data.sectionHeaders := data.header.sectionHeaderNum times elfSectionHeader.value;
seek(elfFile, succ(data.header.sectionHeaderOffset));
for index range 1 to data.header.sectionHeaderNum do
readSectionHeader(elfFile, data.header, data.sectionHeaders[index]);
end for;
index := succ(data.header.nameSectionIndex);
seek(elfFile, succ(data.sectionHeaders[index].offset));
data.sectionNameTable := gets(elfFile, data.sectionHeaders[index].size);
for index range 1 to data.header.sectionHeaderNum do
data.sectionHeaders[index].name :=
fromAsciiz(data.sectionNameTable, succ(data.sectionHeaders[index].nameOffset));
data.sectionNameHash @:= [data.sectionHeaders[index].name] index;
end for;
end if;
end func;
const func array string: readSectionNames (in elfData: data) is
return keys(data.sectionNameHash);
const func elfSectionHeader: getSection (in elfData: data, in string: sectionName) is func
result
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
begin
if sectionName in data.sectionNameHash then
sectionHeader := data.sectionHeaders[data.sectionNameHash[sectionName]];
end if;
end func;
const func string: getSectionData (inout elfData: data, in string: sectionName) is func
result
var string: sectionData is "";
local
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
begin
if sectionName in data.sectionNameHash then
sectionHeader := data.sectionHeaders[data.sectionNameHash[sectionName]];
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
end if;
end func;
const type: elfGnuHashHeader is new struct
var integer: nbuckets is 0;
var integer: symndx is 0;
var integer: maskwords is 0;
var integer: shift2 is 0;
var array integer: bloom_filter is 0 times 0;
var array integer: buckets is 0 times 0;
var array integer: values is 0 times 0;
end struct;
const proc: show (in elfGnuHashHeader: header) is func
begin
writeln("nbuckets: " <& header.nbuckets);
writeln("symndx: " <& header.symndx);
writeln("maskwords: " <& header.maskwords);
writeln("shift2: " <& header.shift2);
end func;
const proc: readGnuHashHeaderLe (in string: stri, inout elfGnuHashHeader: hashHeader) is func
begin
hashHeader.nbuckets := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
hashHeader.symndx := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
hashHeader.maskwords := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
hashHeader.shift2 := bytes2Int(stri[13 fixLen 4], UNSIGNED, LE);
hashHeader.bloom_filter := hashHeader.maskwords times 0;
hashHeader.buckets := hashHeader.nbuckets times 0;
end func;
const proc: readGnuHashHeaderBe (in string: stri, inout elfGnuHashHeader: hashHeader) is func
begin
hashHeader.nbuckets := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
hashHeader.symndx := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
hashHeader.maskwords := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
hashHeader.shift2 := bytes2Int(stri[13 fixLen 4], UNSIGNED, BE);
hashHeader.bloom_filter := hashHeader.maskwords times 0;
hashHeader.buckets := hashHeader.nbuckets times 0;
end func;
const func elfGnuHashHeader: readGnuHashHeader (in string: sectionData, inout integer: pos,
in boolean: isLittleEndian) is func
result
var elfGnuHashHeader: hashHeader is elfGnuHashHeader.value;
local
var string: stri is "";
begin
stri := sectionData[pos ..];
if length(stri) >= ELF_NOTE_HEADER_SIZE then
if isLittleEndian then
readGnuHashHeaderLe(stri, hashHeader);
else
readGnuHashHeaderBe(stri, hashHeader);
end if;
end if;
end func;
const type: elfNoteHeader is new struct
var integer: nameSize is 0;
var integer: descriptionSize is 0;
var integer: noteType is 0;
var string: name is "";
var string: description is "";
end struct;
const proc: show (in elfNoteHeader: header) is func
begin
writeln("nameSize: " <& header.nameSize);
writeln("descriptionSize: " <& header.descriptionSize);
writeln("noteType: " <& header.noteType);
writeln("name: " <& header.name);
writeln("description: " <& literal(header.description));
end func;
const proc: readNoteHeaderLe (in string: stri, inout elfNoteHeader: noteHeader) is func
begin
noteHeader.nameSize := bytes2Int(stri[1 fixLen 4], UNSIGNED, LE);
noteHeader.descriptionSize := bytes2Int(stri[5 fixLen 4], UNSIGNED, LE);
noteHeader.noteType := bytes2Int(stri[9 fixLen 4], UNSIGNED, LE);
end func;
const proc: readNoteHeaderBe (in string: stri, inout elfNoteHeader: noteHeader) is func
begin
noteHeader.nameSize := bytes2Int(stri[1 fixLen 4], UNSIGNED, BE);
noteHeader.descriptionSize := bytes2Int(stri[5 fixLen 4], UNSIGNED, BE);
noteHeader.noteType := bytes2Int(stri[9 fixLen 4], UNSIGNED, BE);
end func;
const func elfNoteHeader: readNoteHeader (in string: sectionData, inout integer: pos,
in boolean: isLittleEndian) is func
result
var elfNoteHeader: noteHeader is elfNoteHeader.value;
local
var string: stri is "";
var integer: alignedNameSize is 0;
var integer: alignedDescriptionSize is 0;
begin
stri := sectionData[pos ..];
if length(stri) >= ELF_NOTE_HEADER_SIZE then
if isLittleEndian then
readNoteHeaderLe(stri, noteHeader);
else
readNoteHeaderBe(stri, noteHeader);
end if;
alignedNameSize := succ(pred(noteHeader.nameSize ) mdiv 4) * 4;
alignedDescriptionSize := succ(pred(noteHeader.descriptionSize) mdiv 4) * 4;
if length(stri) >= alignedNameSize + noteHeader.descriptionSize then
if noteHeader.nameSize > 0 then
noteHeader.name := stri[13 fixLen pred(noteHeader.nameSize)];
if stri[12 + noteHeader.nameSize] <> '\0;' then
raise RANGE_ERROR;
end if;
end if;
noteHeader.description := stri[13 + alignedNameSize fixLen noteHeader.descriptionSize];
pos +:= ELF_NOTE_HEADER_SIZE + alignedNameSize + alignedDescriptionSize;
else
raise RANGE_ERROR;
end if;
elsif stri <> "" then
raise RANGE_ERROR;
end if;
end func;
const func string: getNote (inout elfData: data, in string: sectionName,
in string: noteName) is func
result
var string: note is "";
local
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
var string: sectionData is "";
var integer: pos is 1;
var elfNoteHeader: noteHeader is elfNoteHeader.value;
begin
sectionHeader := getSection(data, sectionName);
if sectionHeader.sectionType = ELF_SHT_NOTE then
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
repeat
noteHeader := readNoteHeader(sectionData, pos, sectionHeader.isLittleEndian);
until noteHeader.name = noteName;
note := noteHeader.description;
end if;
end func;
const func string: getBuildId (inout elfData: data) is
return getNote(data, ".note.gnu.build-id", "GNU");
const type: noteHash is hash [string] string;
const func noteHash: getNotes (inout elfData: data, in string: sectionName) is func
result
var noteHash: notes is noteHash.value;
local
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
var string: sectionData is "";
var integer: pos is 1;
var elfNoteHeader: noteHeader is elfNoteHeader.value;
begin
sectionHeader := getSection(data, sectionName);
if sectionHeader.sectionType = ELF_SHT_NOTE then
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
repeat
noteHeader := readNoteHeader(sectionData, pos, sectionHeader.isLittleEndian);
show(noteHeader);
if noteHeader.name <> "" or noteHeader.description <> "" then
notes @:= [noteHeader.name] noteHeader.description;
end if;
until noteHeader.name = "" and noteHeader.description = "";
end if;
end func;
const type: elfSym is new struct
var integer: nameIndex is 0;
var integer: value is 0;
var integer: size is 0;
var integer: info is 0;
var integer: other is 0;
var integer: shndx is 0;
end struct;
const proc: show (in elfSym: sym) is func
begin
writeln("nameIndex: " <& sym.nameIndex);
writeln("value: " <& sym.value);
writeln("size: " <& sym.size);
writeln("info: " <& sym.info);
writeln("other: " <& sym.other);
writeln("shndx: " <& sym.shndx);
end func;
const proc: readSym32Le (in string: stri, inout elfSym: sym) is func
begin
sym.nameIndex := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
sym.value := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
sym.size := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
sym.info := bytes2Int(stri[13 fixLen 1], UNSIGNED, LE);
sym.other := bytes2Int(stri[14 fixLen 1], UNSIGNED, LE);
sym.shndx := bytes2Int(stri[15 fixLen 2], UNSIGNED, LE);
end func;
const proc: readSym32Be (in string: stri, inout elfSym: sym) is func
begin
sym.nameIndex := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
sym.value := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
sym.size := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
sym.info := bytes2Int(stri[13 fixLen 1], UNSIGNED, BE);
sym.other := bytes2Int(stri[14 fixLen 1], UNSIGNED, BE);
sym.shndx := bytes2Int(stri[15 fixLen 2], UNSIGNED, BE);
end func;
const proc: readSym64Le (in string: stri, inout elfSym: sym) is func
begin
sym.nameIndex := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
sym.info := bytes2Int(stri[ 5 fixLen 1], UNSIGNED, LE);
sym.other := bytes2Int(stri[ 6 fixLen 1], UNSIGNED, LE);
sym.shndx := bytes2Int(stri[ 7 fixLen 2], UNSIGNED, LE);
sym.value := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, LE);
sym.size := bytes2Int(stri[17 fixLen 8], UNSIGNED, LE);
end func;
const proc: readSym64Be (in string: stri, inout elfSym: sym) is func
begin
sym.nameIndex := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
sym.info := bytes2Int(stri[ 5 fixLen 1], UNSIGNED, BE);
sym.other := bytes2Int(stri[ 6 fixLen 1], UNSIGNED, BE);
sym.shndx := bytes2Int(stri[ 7 fixLen 2], UNSIGNED, BE);
sym.value := bytes2Int(stri[ 9 fixLen 8], UNSIGNED, BE);
sym.size := bytes2Int(stri[17 fixLen 8], UNSIGNED, BE);
end func;
const func elfSym: readSym (in string: sectionData, inout integer: pos,
in integer: addressSize, in boolean: isLittleEndian) is func
result
var elfSym: sym is elfSym.value;
local
var string: stri is "";
begin
stri := sectionData[pos ..];
if addressSize = 32 then
if length(stri) >= ELF_SYM32_SIZE then
if isLittleEndian then
readSym32Le(stri, sym);
else
readSym32Be(stri, sym);
end if;
pos +:= ELF_SYM32_SIZE;
else
raise RANGE_ERROR;
end if;
elsif addressSize = 64 then
if length(stri) >= ELF_SYM64_SIZE then
if isLittleEndian then
readSym64Le(stri, sym);
else
readSym64Le(stri, sym);
end if;
pos +:= ELF_SYM64_SIZE;
else
raise RANGE_ERROR;
end if;
end if;
end func;
const func array string: getDynsymNames (inout elfData: data, in string: sectionName,
in string: dynstrSectionName) is func
result
var array string: dynsymNames is 0 times "";
local
var string: dynstr is "";
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
var string: sectionData is "";
var integer: pos is 1;
var elfSym: sym is elfSym.value;
begin
dynstr := getSectionData(data, dynstrSectionName);
sectionHeader := getSection(data, sectionName);
if sectionHeader.sectionType = ELF_SHT_DYNSYM then
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
repeat
sym := readSym(sectionData, pos, sectionHeader.addressSize, sectionHeader.isLittleEndian);
dynsymNames &:= fromAsciiz(dynstr, succ(sym.nameIndex));
until pos > length(sectionData);
end if;
end func;
const func array string: getDynsymNames (inout elfData: data, in string: sectionName) is
return getDynsymNames(data, sectionName, ".dynstr");
const func array string: getDynsymNames (inout elfData: data) is
return getDynsymNames(data, ".dynsym", ".dynstr");
const type: elfDyn is new struct
var integer: tag is 0;
var integer: valOrPtr is 0;
end struct;
const proc: show (in elfDyn: dyn) is func
begin
writeln("tag: " <& dyn.tag);
writeln("valOrPtr: " <& dyn.valOrPtr);
end func;
const proc: readDyn32Le (in string: stri, inout elfDyn: dyn) is func
begin
dyn.tag := bytes2Int(stri[1 fixLen 4], SIGNED, LE);
dyn.valOrPtr := bytes2Int(stri[5 fixLen 4], UNSIGNED, LE);
end func;
const proc: readDyn32Be (in string: stri, inout elfDyn: dyn) is func
begin
dyn.tag := bytes2Int(stri[1 fixLen 4], SIGNED, BE);
dyn.valOrPtr := bytes2Int(stri[5 fixLen 4], UNSIGNED, BE);
end func;
const proc: readDyn64Le (in string: stri, inout elfDyn: dyn) is func
begin
dyn.tag := bytes2Int(stri[1 fixLen 8], SIGNED, LE);
dyn.valOrPtr := bytes2Int(stri[9 fixLen 8], UNSIGNED, LE);
end func;
const proc: readDyn64Be (in string: stri, inout elfDyn: dyn) is func
begin
dyn.tag := bytes2Int(stri[1 fixLen 8], SIGNED, BE);
dyn.valOrPtr := bytes2Int(stri[9 fixLen 8], UNSIGNED, BE);
end func;
const func elfDyn: readDyn (in string: sectionData, inout integer: pos,
in integer: addressSize, in boolean: isLittleEndian) is func
result
var elfDyn: dyn is elfDyn.value;
local
var string: stri is "";
begin
stri := sectionData[pos ..];
if addressSize = 32 then
if length(stri) >= ELF_DYN32_SIZE then
if isLittleEndian then
readDyn32Le(stri, dyn);
else
readDyn32Be(stri, dyn);
end if;
pos +:= ELF_DYN32_SIZE;
else
raise RANGE_ERROR;
end if;
elsif addressSize = 64 then
if length(stri) >= ELF_DYN64_SIZE then
if isLittleEndian then
readDyn64Le(stri, dyn);
else
readDyn64Le(stri, dyn);
end if;
pos +:= ELF_DYN64_SIZE;
else
raise RANGE_ERROR;
end if;
end if;
end func;
const func array string: getDynamicNeeds (inout elfData: data, in string: sectionName,
in string: dynstrSectionName) is func
result
var array string: dynNames is 0 times "";
local
var string: dynstr is "";
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
var string: sectionData is "";
var integer: pos is 1;
var elfDyn: dyn is elfDyn.value;
begin
dynstr := getSectionData(data, dynstrSectionName);
sectionHeader := getSection(data, sectionName);
if sectionHeader.sectionType = ELF_SHT_DYNAMIC then
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
repeat
dyn := readDyn(sectionData, pos, sectionHeader.addressSize, sectionHeader.isLittleEndian);
if dyn.tag = ELF_DT_NEEDED then
dynNames &:= fromAsciiz(dynstr, succ(dyn.valOrPtr));
end if;
until pos > length(sectionData);
end if;
end func;
const func array string: getDynamicNeeds (inout elfData: data, in string: sectionName) is
return getDynamicNeeds(data, sectionName, ".dynstr");
const func array string: getDynamicNeeds (inout elfData: data) is
return getDynamicNeeds(data, ".dynamic", ".dynstr");
const type: elfVerDAux is new struct
var integer: name is 0;
var integer: next is 0;
end struct;
const proc: show (in elfVerDAux: verDAux) is func
begin
writeln("name: " <& verDAux.name);
writeln("next: " <& verDAux.next);
end func;
const proc: readVerDAuxLe (in string: stri, inout elfVerDAux: verDAux) is func
begin
verDAux.name := bytes2Int(stri[1 fixLen 4], UNSIGNED, LE);
verDAux.next := bytes2Int(stri[5 fixLen 4], UNSIGNED, LE);
end func;
const proc: readVerDAuxBe (in string: stri, inout elfVerDAux: verDAux) is func
begin
verDAux.name := bytes2Int(stri[1 fixLen 4], UNSIGNED, BE);
verDAux.next := bytes2Int(stri[5 fixLen 4], UNSIGNED, BE);
end func;
const func elfVerDAux: readVerDAux (in string: sectionData, inout integer: pos,
in boolean: isLittleEndian) is func
result
var elfVerDAux: verDAux is elfVerDAux.value;
local
var string: stri is "";
begin
stri := sectionData[pos ..];
if length(stri) >= ELF_VER_D_AUX_SIZE then
if isLittleEndian then
readVerDAuxLe(stri, verDAux);
else
readVerDAuxBe(stri, verDAux);
end if;
if verDAux.next <> 0 then
pos +:= verDAux.next;
else
pos := 0;
end if;
else
raise RANGE_ERROR;
end if;
end func;
const type: elfVerNAux is new struct
var integer: nameHash is 0;
var integer: flags is 0;
var integer: other is 0;
var integer: nameIndex is 0;
var integer: next is 0;
var string: name is "";
end struct;
const proc: show (in elfVerNAux: verNAux) is func
begin
writeln("nameHash: " <& verNAux.nameHash);
writeln("flags: " <& verNAux.flags);
writeln("other: " <& verNAux.other);
writeln("nameIndex: " <& verNAux.nameIndex);
writeln("next: " <& verNAux.next);
writeln("name: " <& verNAux.name);
end func;
const proc: readVerNAuxLe (in string: stri, inout elfVerNAux: verNAux) is func
begin
verNAux.nameHash := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, LE);
verNAux.flags := bytes2Int(stri[ 5 fixLen 2], UNSIGNED, LE);
verNAux.other := bytes2Int(stri[ 7 fixLen 2], UNSIGNED, LE);
verNAux.nameIndex := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
verNAux.next := bytes2Int(stri[13 fixLen 4], UNSIGNED, LE);
end func;
const proc: readVerNAuxBe (in string: stri, inout elfVerNAux: verNAux) is func
begin
verNAux.nameHash := bytes2Int(stri[ 1 fixLen 4], UNSIGNED, BE);
verNAux.flags := bytes2Int(stri[ 5 fixLen 2], UNSIGNED, BE);
verNAux.other := bytes2Int(stri[ 7 fixLen 2], UNSIGNED, BE);
verNAux.nameIndex := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
verNAux.next := bytes2Int(stri[13 fixLen 4], UNSIGNED, BE);
end func;
const func elfVerNAux: readVerNAux (in string: stri, in boolean: isLittleEndian,
in string: dynstr) is func
result
var elfVerNAux: verNAux is elfVerNAux.value;
begin
if length(stri) >= ELF_VER_N_AUX_SIZE then
if isLittleEndian then
readVerNAuxLe(stri, verNAux);
else
readVerNAuxBe(stri, verNAux);
end if;
verNAux.name := fromAsciiz(dynstr, succ(verNAux.nameIndex));
else
raise RANGE_ERROR;
end if;
end func;
const type: elfVerNeed is new struct
var integer: version is 0;
var integer: count is 0;
var integer: fileNameIndex is 0;
var integer: aux is 0;
var integer: next is 0;
var string: fileName is "";
end struct;
const proc: show (in elfVerNeed: verNeed) is func
begin
writeln("version: " <& verNeed.version);
writeln("count: " <& verNeed.count);
writeln("fileNameIndex: " <& verNeed.fileNameIndex);
writeln("aux: " <& verNeed.aux);
writeln("next: " <& verNeed.next);
writeln("fileName: " <& verNeed.fileName);
end func;
const proc: readVerNeedLe (in string: stri, inout elfVerNeed: verNeed) is func
begin
verNeed.version := bytes2Int(stri[ 1 fixLen 2], UNSIGNED, LE);
verNeed.count := bytes2Int(stri[ 3 fixLen 2], UNSIGNED, LE);
verNeed.fileNameIndex := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, LE);
verNeed.aux := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, LE);
verNeed.next := bytes2Int(stri[13 fixLen 4], UNSIGNED, LE);
end func;
const proc: readVerNeedBe (in string: stri, inout elfVerNeed: verNeed) is func
begin
verNeed.version := bytes2Int(stri[ 1 fixLen 2], UNSIGNED, BE);
verNeed.count := bytes2Int(stri[ 3 fixLen 2], UNSIGNED, BE);
verNeed.fileNameIndex := bytes2Int(stri[ 5 fixLen 4], UNSIGNED, BE);
verNeed.aux := bytes2Int(stri[ 9 fixLen 4], UNSIGNED, BE);
verNeed.next := bytes2Int(stri[13 fixLen 4], UNSIGNED, BE);
end func;
const func elfVerNeed: readVerNeed (in string: stri, in boolean: isLittleEndian,
in string: dynstr) is func
result
var elfVerNeed: verNeed is elfVerNeed.value;
begin
if length(stri) >= ELF_VER_NEED_SIZE then
if isLittleEndian then
readVerNeedLe(stri, verNeed);
else
readVerNeedBe(stri, verNeed);
end if;
verNeed.fileName := fromAsciiz(dynstr, succ(verNeed.fileNameIndex));
else
raise RANGE_ERROR;
end if;
end func;
const func array string: getVerNeeds (inout elfData: data, in string: sectionName,
in string: dynstrSectionName) is func
result
var array string: verNeedNames is 0 times "";
local
var string: dynstr is "";
var string: addressSizeStri is "";
var elfSectionHeader: sectionHeader is elfSectionHeader.value;
var string: sectionData is "";
var integer: verNeedPos is 1;
var elfVerNeed: verNeed is elfVerNeed.value;
var integer: verNAuxPos is 1;
var integer: count is 0;
var elfVerNAux: verNAux is elfVerNAux.value;
begin
dynstr := getSectionData(data, dynstrSectionName);
addressSizeStri := "(" <& data.header.addressSize <& "bit)";
sectionHeader := getSection(data, sectionName);
if sectionHeader.sectionType = ELF_SHT_GNU_verneed then
seek(data.elfFile, succ(sectionHeader.offset));
sectionData := gets(data.elfFile, sectionHeader.size);
repeat
verNeed := readVerNeed(sectionData[verNeedPos ..], sectionHeader.isLittleEndian, dynstr);
if verNeed.count <> 0 then
verNAuxPos := verNeedPos + verNeed.aux;
for count range 1 to verNeed.count do
verNAux := readVerNAux(sectionData[verNAuxPos ..], sectionHeader.isLittleEndian, dynstr);
verNeedNames &:= verNeed.fileName & "(" & verNAux.name & ")" & addressSizeStri;
if verNAux.next <> 0 then
verNAuxPos +:= verNAux.next;
else
verNAuxPos := 0;
end if;
end for;
if verNAuxPos <> 0 then
raise RANGE_ERROR;
end if;
end if;
if verNeed.next <> 0 then
verNeedPos +:= verNeed.next;
else
verNeedPos := 0;
end if;
until verNeedPos = 0;
end if;
end func;
const func array string: getVerNeeds (inout elfData: data, in string: sectionName) is
return getVerNeeds(data, sectionName, ".dynstr");
const func array string: getVerNeeds (inout elfData: data) is
return getVerNeeds(data, ".gnu.version_r", ".dynstr");