mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 22:28:06 +02:00
706 lines
20 KiB
ObjectPascal
706 lines
20 KiB
ObjectPascal
{
|
|
Copyright (c) 1998-2006 by Peter Vreman
|
|
|
|
Contains ELF definitions
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
unit elfbase;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
const
|
|
EI_MAG0 = 0;
|
|
ELFMAG0 = $7F;
|
|
EI_MAG1 = 1;
|
|
ELFMAG1 = ord('E');
|
|
EI_MAG2 = 2;
|
|
ELFMAG2 = ord('L');
|
|
EI_MAG3 = 3;
|
|
ELFMAG3 = ord('F');
|
|
EI_CLASS = 4;
|
|
ELFCLASSNONE = 0;
|
|
ELFCLASS32 = 1;
|
|
ELFCLASS64 = 2;
|
|
EI_DATA = 5;
|
|
ELFDATANONE = 0;
|
|
ELFDATA2LSB = 1;
|
|
ELFDATA2MSB = 2;
|
|
EI_VERSION = 6;
|
|
EI_OSABI = 7;
|
|
ELFOSABI_NONE = 0; { UNIX System V ABI }
|
|
ELFOSABI_HPUX = 1; { HP-UX operating system }
|
|
ELFOSABI_NETBSD = 2; { NetBSD }
|
|
ELFOSABI_LINUX = 3; { GNU/Linux }
|
|
ELFOSABI_HURD = 4; { GNU/Hurd }
|
|
ELFOSABI_SOLARIS = 6; { Solaris }
|
|
ELFOSABI_AIX = 7; { AIX }
|
|
ELFOSABI_IRIX = 8; { IRIX }
|
|
ELFOSABI_FREEBSD = 9; { FreeBSD }
|
|
ELFOSABI_TRU64 = 10; { TRU64 UNIX }
|
|
ELFOSABI_MODESTO = 11; { Novell Modesto }
|
|
ELFOSABI_OPENBSD = 12; { OpenBSD }
|
|
ELFOSABI_OPENVMS = 13; { OpenVMS }
|
|
ELFOSABI_NSK = 14; { Hewlett-Packard Non-Stop Kernel }
|
|
ELFOSABI_AROS = 15; { AROS }
|
|
ELFOSABI_FENIXOS = 16; { FenixOS }
|
|
ELFOSABI_C6000_ELFABI = 64; { Bare-metal TMS320C6000 }
|
|
ELFOSABI_C6000_LINUX = 65; { Linux TMS320C6000 }
|
|
ELFOSABI_ARM = 97; { ARM }
|
|
ELFOSABI_STANDALONE = 255; { Standalone (embedded) application }
|
|
|
|
EI_ABIVERSION = 8;
|
|
EI_PAD = 9;
|
|
|
|
{ ELFHeader.e_type }
|
|
ET_NONE = 0;
|
|
ET_REL = 1;
|
|
ET_EXEC = 2;
|
|
ET_DYN = 3;
|
|
ET_CORE = 4;
|
|
|
|
{ ELFHeader.e_machine }
|
|
EM_SPARC = 2;
|
|
EM_386 = 3;
|
|
EM_M68K = 4;
|
|
EM_MIPS = 8;
|
|
EM_PPC = 20;
|
|
EM_ARM = 40;
|
|
EM_X86_64 = 62;
|
|
|
|
{ ElfSechdr.sh_num }
|
|
SHN_UNDEF = 0;
|
|
SHN_LORESERVE = $FF00;
|
|
SHN_ABS = $fff1;
|
|
SHN_COMMON = $fff2;
|
|
|
|
{ ElfSechdr.sh_type }
|
|
SHT_NULL = 0;
|
|
SHT_PROGBITS = 1;
|
|
SHT_SYMTAB = 2;
|
|
SHT_STRTAB = 3;
|
|
SHT_RELA = 4;
|
|
SHT_HASH = 5;
|
|
SHT_DYNAMIC = 6;
|
|
SHT_NOTE = 7;
|
|
SHT_NOBITS = 8;
|
|
SHT_REL = 9;
|
|
SHT_SHLIB = 10;
|
|
SHT_DYNSYM = 11;
|
|
SHT_INIT_ARRAY = 14;
|
|
SHT_FINI_ARRAY = 15;
|
|
SHT_PREINIT_ARRAY = 16;
|
|
SHT_GROUP = 17;
|
|
SHT_SYMTAB_SHNDX = 18;
|
|
SHT_GNU_ATTRIBUTES = $6ffffff5;
|
|
SHT_GNU_HASH = $6ffffff6;
|
|
SHT_GNU_LIBLIST = $6ffffff7;
|
|
SHT_GNU_verdef = $6ffffffd;
|
|
SHT_GNU_verneed = $6ffffffe;
|
|
SHT_GNU_versym = $6fffffff;
|
|
SHT_ARM_ATTRIBUTES = $70000003;
|
|
|
|
{ ElfSechdr.sh_flags }
|
|
SHF_WRITE = 1;
|
|
SHF_ALLOC = 2;
|
|
SHF_EXECINSTR = 4;
|
|
SHF_MERGE = 16;
|
|
SHF_STRINGS = 32;
|
|
SHF_INFO_LINK = 64;
|
|
SHF_LINK_ORDER = 128;
|
|
SHF_OS_NONCONFORMING = 256;
|
|
SHF_GROUP = 512;
|
|
SHF_TLS = 1024;
|
|
|
|
STB_LOCAL = 0;
|
|
STB_GLOBAL = 1;
|
|
STB_WEAK = 2;
|
|
|
|
STT_NOTYPE = 0;
|
|
STT_OBJECT = 1;
|
|
STT_FUNC = 2;
|
|
STT_SECTION = 3;
|
|
STT_FILE = 4;
|
|
STT_COMMON = 5;
|
|
STT_TLS = 6;
|
|
STT_GNU_IFUNC = 10;
|
|
|
|
STV_DEFAULT = 0;
|
|
STV_INTERNAL = 1;
|
|
STV_HIDDEN = 2;
|
|
STV_PROTECTED = 3;
|
|
|
|
{ program header types }
|
|
PT_NULL = 0;
|
|
PT_LOAD = 1;
|
|
PT_DYNAMIC = 2;
|
|
PT_INTERP = 3;
|
|
PT_NOTE = 4;
|
|
PT_SHLIB = 5;
|
|
PT_PHDR = 6;
|
|
PT_TLS = 7;
|
|
PT_LOOS = $60000000;
|
|
PT_HIOS = $6FFFFFFF;
|
|
PT_LOPROC = $70000000;
|
|
PT_HIPROC = $7FFFFFFF;
|
|
PT_GNU_EH_FRAME = PT_LOOS + $474e550; { Frame unwind information }
|
|
PT_GNU_STACK = PT_LOOS + $474e551; { Stack flags }
|
|
PT_GNU_RELRO = PT_LOOS + $474e552; { Read-only after relocation }
|
|
|
|
{ program header flags }
|
|
PF_X = 1;
|
|
PF_W = 2;
|
|
PF_R = 4;
|
|
PF_MASKOS = $0FF00000; { OS-specific reserved bits }
|
|
PF_MASKPROC = $F0000000; { Processor-specific reserved bits }
|
|
|
|
{ .dynamic tags }
|
|
DT_NULL = 0;
|
|
DT_NEEDED = 1;
|
|
DT_PLTRELSZ = 2;
|
|
DT_PLTGOT = 3;
|
|
DT_HASH = 4;
|
|
DT_STRTAB = 5;
|
|
DT_SYMTAB = 6;
|
|
DT_RELA = 7;
|
|
DT_RELASZ = 8;
|
|
DT_RELAENT = 9;
|
|
DT_STRSZ = 10;
|
|
DT_SYMENT = 11;
|
|
DT_INIT = 12;
|
|
DT_FINI = 13;
|
|
DT_SONAME = 14;
|
|
DT_RPATH = 15;
|
|
DT_SYMBOLIC = 16;
|
|
DT_REL = 17;
|
|
DT_RELSZ = 18;
|
|
DT_RELENT = 19;
|
|
DT_PLTREL = 20;
|
|
DT_DEBUG = 21;
|
|
DT_TEXTREL = 22;
|
|
DT_JMPREL = 23;
|
|
DT_BIND_NOW = 24;
|
|
DT_INIT_ARRAY = 25;
|
|
DT_FINI_ARRAY = 26;
|
|
DT_INIT_ARRAYSZ = 27;
|
|
DT_FINI_ARRAYSZ = 28;
|
|
DT_RUNPATH = 29;
|
|
DT_FLAGS = 30;
|
|
DT_ENCODING = 32;
|
|
DT_PREINIT_ARRAY = 32;
|
|
DT_PREINIT_ARRAYSZ = 33;
|
|
DT_NUM = 34;
|
|
DT_LOOS = $6000000D;
|
|
DT_HIOS = $6ffff000;
|
|
DT_LOPROC = $70000000;
|
|
DT_HIPROC = $7fffffff;
|
|
|
|
DT_RELACOUNT = $6ffffff9;
|
|
DT_RELCOUNT = $6ffffffa;
|
|
DT_FLAGS_1 = $6ffffffb;
|
|
DT_VERDEF = $6ffffffc;
|
|
DT_VERDEFNUM = $6ffffffd;
|
|
DT_VERNEED = $6ffffffe;
|
|
DT_VERNEEDNUM = $6fffffff;
|
|
{ GNU extension to Solaris versioning scheme }
|
|
DT_VERSYM = $6ffffff0;
|
|
|
|
GRP_COMDAT = 1;
|
|
|
|
|
|
{ DT_FLAGS }
|
|
DF_ORIGIN = 1;
|
|
DF_SYMBOLIC = 2; // supersedes DT_SYMBOLIC
|
|
DF_TEXTREL = 4; // supersedes DT_TEXTREL
|
|
DF_BIND_NOW = 8; // supersedes DT_BIND_NOW
|
|
DF_STATIC_TLS = 16;
|
|
|
|
{ DT_FLAGS_1 }
|
|
DF_1_NOW = $01;
|
|
DF_1_GLOBAL = $02;
|
|
DF_1_GROUP = $04;
|
|
DF_1_NODELETE = $08;
|
|
DF_1_LOADFLTR = $10;
|
|
DF_1_INITFIRST = $20;
|
|
DF_1_NOOPEN = $40;
|
|
DF_1_ORIGIN = $80;
|
|
DF_1_DIRECT = $100;
|
|
DF_1_TRANS = $200;
|
|
DF_1_INTERPOSE = $400;
|
|
DF_1_NODEFLIB = $800;
|
|
DF_1_NODUMP = $1000;
|
|
DF_1_CONFALT = $2000;
|
|
|
|
type
|
|
TElfIdent = array[0..15] of byte;
|
|
|
|
{ Structures which are written directly to the output file }
|
|
TElf32header=record
|
|
e_ident : TElfIdent;
|
|
e_type : word;
|
|
e_machine : word;
|
|
e_version : longword;
|
|
e_entry : longword; { entrypoint }
|
|
e_phoff : longword; { program header offset }
|
|
e_shoff : longword; { sections header offset }
|
|
e_flags : longword;
|
|
e_ehsize : word; { elf header size in bytes }
|
|
e_phentsize : word; { size of an entry in the program header array }
|
|
e_phnum : word; { 0..e_phnum-1 of entrys }
|
|
e_shentsize : word; { size of an entry in sections header array }
|
|
e_shnum : word; { 0..e_shnum-1 of entrys }
|
|
e_shstrndx : word; { index of string section header }
|
|
end;
|
|
|
|
TElf32sechdr=record
|
|
sh_name : longword;
|
|
sh_type : longword;
|
|
sh_flags : longword;
|
|
sh_addr : longword;
|
|
sh_offset : longword;
|
|
sh_size : longword;
|
|
sh_link : longword;
|
|
sh_info : longword;
|
|
sh_addralign : longword;
|
|
sh_entsize : longword;
|
|
end;
|
|
|
|
TElf32proghdr=record
|
|
p_type : longword;
|
|
p_offset : longword;
|
|
p_vaddr : longword;
|
|
p_paddr : longword;
|
|
p_filesz : longword;
|
|
p_memsz : longword;
|
|
p_flags : longword;
|
|
p_align : longword;
|
|
end;
|
|
|
|
TElf32reloc=record
|
|
address : longword;
|
|
info : longword; { bit 0-7: type, 8-31: symbol }
|
|
addend : longint;
|
|
end;
|
|
|
|
TElf32symbol=record
|
|
st_name : longword;
|
|
st_value : longword;
|
|
st_size : longword;
|
|
st_info : byte; { bit 0-3: type, 4-7: bind }
|
|
st_other : byte;
|
|
st_shndx : word;
|
|
end;
|
|
|
|
TElf32Dyn=record
|
|
d_tag: longword;
|
|
case integer of
|
|
0: (d_val: longword);
|
|
1: (d_ptr: longword);
|
|
end;
|
|
|
|
telf64header=record
|
|
e_ident : TElfIdent;
|
|
e_type : word;
|
|
e_machine : word;
|
|
e_version : longword;
|
|
e_entry : qword; { entrypoint }
|
|
e_phoff : qword; { program header offset }
|
|
e_shoff : qword; { sections header offset }
|
|
e_flags : longword;
|
|
e_ehsize : word; { elf header size in bytes }
|
|
e_phentsize : word; { size of an entry in the program header array }
|
|
e_phnum : word; { 0..e_phnum-1 of entrys }
|
|
e_shentsize : word; { size of an entry in sections header array }
|
|
e_shnum : word; { 0..e_shnum-1 of entrys }
|
|
e_shstrndx : word; { index of string section header }
|
|
end;
|
|
|
|
TElf64sechdr=record
|
|
sh_name : longword;
|
|
sh_type : longword;
|
|
sh_flags : qword;
|
|
sh_addr : qword;
|
|
sh_offset : qword;
|
|
sh_size : qword;
|
|
sh_link : longword;
|
|
sh_info : longword;
|
|
sh_addralign : qword;
|
|
sh_entsize : qword;
|
|
end;
|
|
|
|
telf64proghdr=record
|
|
p_type : longword;
|
|
p_flags : longword;
|
|
p_offset : qword;
|
|
p_vaddr : qword;
|
|
p_paddr : qword;
|
|
p_filesz : qword;
|
|
p_memsz : qword;
|
|
p_align : qword;
|
|
end;
|
|
|
|
telf64reloc=record
|
|
address : qword;
|
|
info : qword; { bit 0-31: type, 32-63: symbol }
|
|
addend : int64; { signed! }
|
|
end;
|
|
|
|
telf64symbol=record
|
|
st_name : longword;
|
|
st_info : byte; { bit 0-3: type, 4-7: bind }
|
|
st_other : byte;
|
|
st_shndx : word;
|
|
st_value : qword;
|
|
st_size : qword;
|
|
end;
|
|
|
|
TElf64Dyn=record
|
|
d_tag: qword;
|
|
case integer of
|
|
0: (d_val: qword);
|
|
1: (d_ptr: qword);
|
|
end;
|
|
|
|
{ The following records are same for 32 and 64 bit ELF files }
|
|
TElfVerdef=record
|
|
vd_version: word; { =VER_DEF_CURRENT }
|
|
vd_flags: word;
|
|
vd_ndx: word;
|
|
vd_cnt: word; { number of verdaux records }
|
|
vd_hash: longword; { ELF hash of version name }
|
|
vd_aux: longword; { offset to verdaux records }
|
|
vd_next: longword; { offset to next verdef record }
|
|
end;
|
|
|
|
TElfVerdaux=record
|
|
vda_name: longword;
|
|
vda_next: longword;
|
|
end;
|
|
|
|
TElfVerneed=record
|
|
vn_version: word; { =VER_NEED_CURRENT }
|
|
vn_cnt: word;
|
|
vn_file: longword;
|
|
vn_aux: longword;
|
|
vn_next: longword;
|
|
end;
|
|
|
|
TElfVernaux=record
|
|
vna_hash: longword;
|
|
vna_flags: word;
|
|
vna_other: word;
|
|
vna_name: longword;
|
|
vna_next: longword;
|
|
end;
|
|
|
|
const
|
|
VERSYM_VERSION = $7FFF;
|
|
VERSYM_HIDDEN = $8000;
|
|
VER_NDX_LOCAL = 0;
|
|
VER_NDX_GLOBAL = 1;
|
|
|
|
{ TElfverdef.vd_version }
|
|
VER_DEF_CURRENT = 1;
|
|
{ TElfverneed.vn_version }
|
|
VER_NEED_CURRENT = 1;
|
|
{ TElfverdef.vn_flags }
|
|
VER_FLG_BASE = 1;
|
|
VER_FLG_WEAK = 2;
|
|
VER_FLG_INFO = 4;
|
|
|
|
procedure MayBeSwapHeader(var h : telf32header);
|
|
procedure MayBeSwapHeader(var h : telf64header);
|
|
procedure MayBeSwapHeader(var h : telf32proghdr);
|
|
procedure MayBeSwapHeader(var h : telf64proghdr);
|
|
procedure MaybeSwapSecHeader(var h : telf32sechdr);
|
|
procedure MaybeSwapSecHeader(var h : telf64sechdr);
|
|
procedure MaybeSwapElfSymbol(var h : telf32symbol);
|
|
procedure MaybeSwapElfSymbol(var h : telf64symbol);
|
|
procedure MaybeSwapElfReloc(var h : telf32reloc);
|
|
procedure MaybeSwapElfReloc(var h : telf64reloc);
|
|
procedure MaybeSwapElfDyn(var h : telf32dyn);
|
|
procedure MaybeSwapElfDyn(var h : telf64dyn);
|
|
procedure MaybeSwapElfverdef(var h: TElfverdef);
|
|
procedure MaybeSwapElfverdaux(var h: TElfverdaux);
|
|
procedure MaybeSwapElfverneed(var h: TElfverneed);
|
|
procedure MaybeSwapElfvernaux(var h: TElfvernaux);
|
|
|
|
function GetElfSymbolVisibility(other: byte): byte; inline;
|
|
procedure SetElfSymbolVisibility(var other: byte; vis: byte); inline;
|
|
|
|
implementation
|
|
|
|
uses
|
|
systems;
|
|
|
|
procedure MayBeSwapHeader(var h : telf32header);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
e_type:=swapendian(e_type);
|
|
e_machine:=swapendian(e_machine);
|
|
e_version:=swapendian(e_version);
|
|
e_entry:=swapendian(e_entry);
|
|
e_phoff:=swapendian(e_phoff);
|
|
e_shoff:=swapendian(e_shoff);
|
|
e_flags:=swapendian(e_flags);
|
|
e_ehsize:=swapendian(e_ehsize);
|
|
e_phentsize:=swapendian(e_phentsize);
|
|
e_phnum:=swapendian(e_phnum);
|
|
e_shentsize:=swapendian(e_shentsize);
|
|
e_shnum:=swapendian(e_shnum);
|
|
e_shstrndx:=swapendian(e_shstrndx);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MayBeSwapHeader(var h : telf64header);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
e_type:=swapendian(e_type);
|
|
e_machine:=swapendian(e_machine);
|
|
e_version:=swapendian(e_version);
|
|
e_entry:=swapendian(e_entry);
|
|
e_phoff:=swapendian(e_phoff);
|
|
e_shoff:=swapendian(e_shoff);
|
|
e_flags:=swapendian(e_flags);
|
|
e_ehsize:=swapendian(e_ehsize);
|
|
e_phentsize:=swapendian(e_phentsize);
|
|
e_phnum:=swapendian(e_phnum);
|
|
e_shentsize:=swapendian(e_shentsize);
|
|
e_shnum:=swapendian(e_shnum);
|
|
e_shstrndx:=swapendian(e_shstrndx);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MayBeSwapHeader(var h : telf32proghdr);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
p_align:=swapendian(p_align);
|
|
p_filesz:=swapendian(p_filesz);
|
|
p_flags:=swapendian(p_flags);
|
|
p_memsz:=swapendian(p_memsz);
|
|
p_offset:=swapendian(p_offset);
|
|
p_paddr:=swapendian(p_paddr);
|
|
p_type:=swapendian(p_type);
|
|
p_vaddr:=swapendian(p_vaddr);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MayBeSwapHeader(var h : telf64proghdr);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
p_align:=swapendian(p_align);
|
|
p_filesz:=swapendian(p_filesz);
|
|
p_flags:=swapendian(p_flags);
|
|
p_memsz:=swapendian(p_memsz);
|
|
p_offset:=swapendian(p_offset);
|
|
p_paddr:=swapendian(p_paddr);
|
|
p_type:=swapendian(p_type);
|
|
p_vaddr:=swapendian(p_vaddr);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapSecHeader(var h : telf32sechdr);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
sh_name:=swapendian(sh_name);
|
|
sh_type:=swapendian(sh_type);
|
|
sh_flags:=swapendian(sh_flags);
|
|
sh_addr:=swapendian(sh_addr);
|
|
sh_offset:=swapendian(sh_offset);
|
|
sh_size:=swapendian(sh_size);
|
|
sh_link:=swapendian(sh_link);
|
|
sh_info:=swapendian(sh_info);
|
|
sh_addralign:=swapendian(sh_addralign);
|
|
sh_entsize:=swapendian(sh_entsize);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapSecHeader(var h : telf64sechdr);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
sh_name:=swapendian(sh_name);
|
|
sh_type:=swapendian(sh_type);
|
|
sh_flags:=swapendian(sh_flags);
|
|
sh_addr:=swapendian(sh_addr);
|
|
sh_offset:=swapendian(sh_offset);
|
|
sh_size:=swapendian(sh_size);
|
|
sh_link:=swapendian(sh_link);
|
|
sh_info:=swapendian(sh_info);
|
|
sh_addralign:=swapendian(sh_addralign);
|
|
sh_entsize:=swapendian(sh_entsize);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfSymbol(var h : telf32symbol);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
st_name:=swapendian(st_name);
|
|
st_value:=swapendian(st_value);
|
|
st_size:=swapendian(st_size);
|
|
st_shndx:=swapendian(st_shndx);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfSymbol(var h : telf64symbol);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
st_name:=swapendian(st_name);
|
|
st_value:=swapendian(st_value);
|
|
st_size:=swapendian(st_size);
|
|
st_shndx:=swapendian(st_shndx);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfReloc(var h : telf32reloc);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
address:=swapendian(address);
|
|
info:=swapendian(info);
|
|
addend:=swapendian(addend);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfReloc(var h : telf64reloc);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
address:=swapendian(address);
|
|
info:=swapendian(info);
|
|
addend:=swapendian(addend);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfDyn(var h : telf32dyn);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
d_tag:=swapendian(d_tag);
|
|
d_val:=swapendian(d_val);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfDyn(var h : telf64dyn);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
d_tag:=swapendian(d_tag);
|
|
d_val:=swapendian(d_val);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfverdef(var h: TElfverdef);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
vd_version:=swapendian(vd_version);
|
|
vd_flags:=swapendian(vd_flags);
|
|
vd_ndx:=swapendian(vd_ndx);
|
|
vd_cnt:=swapendian(vd_cnt);
|
|
vd_hash:=swapendian(vd_hash);
|
|
vd_aux:=swapendian(vd_aux);
|
|
vd_next:=swapendian(vd_next);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfverdaux(var h: TElfverdaux);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
vda_name:=swapendian(vda_name);
|
|
vda_next:=swapendian(vda_next);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfverneed(var h: TElfverneed);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
vn_version:=swapendian(vn_version);
|
|
vn_cnt:=swapendian(vn_cnt);
|
|
vn_file:=swapendian(vn_file);
|
|
vn_aux:=swapendian(vn_aux);
|
|
vn_next:=swapendian(vn_next);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure MaybeSwapElfvernaux(var h: TElfvernaux);
|
|
begin
|
|
if source_info.endian<>target_info.endian then
|
|
with h do
|
|
begin
|
|
vna_hash:=swapendian(vna_hash);
|
|
vna_flags:=swapendian(vna_flags);
|
|
vna_other:=swapendian(vna_other);
|
|
vna_name:=swapendian(vna_name);
|
|
vna_next:=swapendian(vna_next);
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetElfSymbolVisibility(other: byte): byte; inline;
|
|
begin
|
|
result:=other and 3;
|
|
end;
|
|
|
|
procedure SetElfSymbolVisibility(var other: byte; vis: byte);
|
|
begin
|
|
other:=(other and not(3)) or vis;
|
|
end;
|
|
|
|
end.
|