Try something else

This commit is contained in:
Peter Jones 2020-10-23 10:34:54 -04:00
parent 4e124d35ab
commit bbdc840beb
10 changed files with 689 additions and 197 deletions

View file

@ -132,12 +132,13 @@ EXPORT_LDFLAGS ?=
ifeq ($(ARCH),ia64)
EXPORT_CFLAGS += -mfixed-range=f32-f127
EXPORT_LDFLAGS += -m elf64_ia64
ARCH_ALIASES =
endif
ifeq ($(ARCH),ia32)
EXPORT_CFLAGS += -mno-mmx -mno-sse
EXPORT_LDFLAGS += --no-ld-generated-unwind-info
EXPORT_LDFLAGS += --no-ld-generated-unwind-info -m elf_i386
ifeq ($(HOSTARCH),x64)
ARCH3264 = -m32
endif
@ -161,7 +162,7 @@ ifeq ($(ARCH),x64)
endif
EXPORT_CFLAGS += -mno-red-zone
EXPORT_LDFLAGS += --no-ld-generated-unwind-info
EXPORT_LDFLAGS += --no-ld-generated-unwind-info -m elf_x86_64
ifeq ($(HOSTARCH),ia32)
ARCH3264 = -m64
endif
@ -178,18 +179,20 @@ endif
ifeq ($(ARCH),mips64el)
EXPORT_CFLAGS += -march=mips64r2 -EL
EXPORT_LDFLAGS += -EL
EXPORT_LDFLAGS += -EL -m elf64ltsmip
ARCH3264 = -mabi=64
ARCH_ALIASES =
endif
ifeq ($(ARCH),aa64)
ARCH_ALIASES = aarch64
EXPORT_LDFLAGS += aarch64elf
endif
ifeq ($(ARCH),arm)
ARCH_ALIASES = armv6 armv7
EXPORT_CFLAGS += -marm
EXPORT_LDFLAGS += armelf_linux_eabi
endif
#
@ -234,7 +237,7 @@ endif
ASFLAGS += $(ARCH3264)
EXPORT_LDFLAGS += -nostdlib --warn-common --no-undefined --fatal-warnings \
--build-id=sha1 --no-eh-frame-hdr \
--orphan-handling=error
--orphan-handling=place
LDFLAGS += $(EXPORT_LDFLAGS)
ifneq ($(ARCH),arm)

View file

@ -35,12 +35,19 @@
#
%.efi: %.so
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
-j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
-j .reloc $(FORMAT) $*.so $@
$(OBJCOPY) \
--file-alignment 512 --section-alignment 4096 \
-j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
-j .rela -j '.rel.*' -j '.rela.*' -j '.rel*' -j '.rela*' \
-j .reloc \
-j '.debug*' -j '.eh_frame*' -j .note.gnu.build-id \
$(FORMAT) $*.so $@
%.efi.debug: %.so
$(OBJCOPY) $(FORMAT) $*.so $@
$(OBJCOPY) \
--file-alignment 512 --section-alignment 4096 \
-j '.debug*' -j '.eh_frame*' -j .note.gnu.build-id \
$(FORMAT) $*.so $@
%.so: %.o
$(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES)

View file

@ -45,7 +45,7 @@ LINUX_HEADERS = /usr/src/sys/build
CPPFLAGS += -D__KERNEL__ -I$(LINUX_HEADERS)/include
CRTOBJS = $(TOPDIR)/$(ARCH)/gnuefi/crt0-efi-$(ARCH).o
LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_efi.lds
LDSCRIPT = $(TOPDIR)/gnuefi/efi.lds
ifneq (,$(findstring FreeBSD,$(OS)))
LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_fbsd_efi.lds
endif

View file

@ -54,6 +54,7 @@ reloc_aa64.o: CFLAGS += -fno-jump-tables
crt0.debug : crt0-efi-$(ARCH).o
$(OBJCOPY) \
--file-alignment 512 --section-alignment 4096 \
--only-keep-debug \
$(FORMAT) $^ $@
@ -76,10 +77,10 @@ ifneq (,$(findstring FreeBSD,$(OS)))
ifeq ($(ARCH),x64)
@$(INSTALL) -v -m 644 $(SRCDIR)/elf_$(ARCH)_fbsd_efi.lds $(INSTALLROOT)$(LIBDIR)/gnuefi/$(ARCH)/efi.lds
else
@$(INSTALL) -v -m 644 $(SRCDIR)/elf_$(ARCH)_efi.lds $(INSTALLROOT)$(LIBDIR)/gnuefi/$(ARCH)/efi.lds
@$(INSTALL) -v -m 644 $(SRCDIR)/efi.lds $(INSTALLROOT)$(LIBDIR)/gnuefi/$(ARCH)/efi.lds
endif
else
@$(INSTALL) -v -m 644 $(SRCDIR)/elf_$(ARCH)_efi.lds $(INSTALLROOT)$(LIBDIR)/gnuefi/$(ARCH)/efi.lds
@$(INSTALL) -v -m 644 $(SRCDIR)/efi.lds $(INSTALLROOT)$(LIBDIR)/gnuefi/$(ARCH)/efi.lds
endif
install_compat: install

View file

@ -43,8 +43,8 @@ extern unsigned long _DYNAMIC;
static void EFIAPI ctors(UINTN ldbase);
static void EFIAPI dtors(UINTN ldbase);
extern EFI_STATUS _relocate(unsigned long ldbase, Elf_Dyn *dyn,
EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
extern EFI_STATUS EFIAPI _relocate(unsigned long ldbase, Elf_Dyn *dyn,
EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
EFI_STATUS EFIAPI
_start(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
@ -156,6 +156,12 @@ static void EFIAPI dtors(UINTN ldbase)
* Hand-craft a dummy .reloc section so EFI knows it's a relocatable
* executable:
*/
#if defined(__i386__) && 0
__asm__(".section .reloc, \"a\", @0\n"
".4byte 0\n"
".4byte 0\n"
".2byte 0\n");
#elif 0
struct
__attribute__((__packed__))
reloc
@ -166,6 +172,7 @@ struct
};
struct reloc __attribute__((__section__(".reloc"))) dotreloc = {0, 10, 0};
#endif
static void
__attribute__((__unused__))
@ -189,6 +196,8 @@ printval_(EFI_SYSTEM_TABLE *systab, int size, uint64_t value)
case 8:
default:
shift = 60;
if (!(value & 0xffffffff00000000ull))
shift >>= 1;
break;
}
mask = 0xfull << shift;

96
gnuefi/efi.lds Normal file
View file

@ -0,0 +1,96 @@
SECTIONS
{
. = 0;
ImageBase = .;
/*
.text 0x1000 : ALIGN(4096)
{
_text = .;
*(.init)
_start = .;
*(.text)
*(.text.*)
*(.fini)
*(.plt)
*(.plt.got)
*(.gnu.linkonce.t.*)
. = ALIGN(4096);
_etext = .;
_text_size = _etext - _text;
}
*/
/*
* We have to have a some kind of relocations, or else the loader doesn't
* believe this is position independent, and will try to load us at e.g.
* 0x1000, which will fail.
*/
. = SIZEOF_HEADERS;
. = NEXT(4096);
.reloc ALIGN(4096) : ALIGN(4096)
{
_reloc = .;
/*
* Hand-craft a dummy .reloc entry so EFI knows it's a relocatable
* executable.
*/
LONG(0);
LONG(10);
SHORT(0);
_ereloc = .;
_reloc_size = _ereloc - _reloc;
}
. = ALIGN(4096);
_text = ADDR(.text);
_etext = ADDR(.text) + SIZEOF(.text);
_reloc = ADDR(.reloc);
_ereloc = ADDR(.reloc) + SIZEOF(.reloc);
_data = ADDR(.data);
_edata = ADDR(.data) + SIZEOF(.data);
_bss = ADDR(.bss);
_ebss = ADDR(.bss) + SIZEOF(.bss);
_rodata = ADDR(.rodata);
_erodata = ADDR(.rodata) + SIZEOF(.rodata);
/*
_data.rel = ADDR(.data.rel);
_edata.rel = ADDR(.data.rel) + SIZEOF(.data.rel);
_data.rel.local = ADDR(.data.rel.local);
_edata.rel.local = ADDR(.data.rel.local) + SIZEOF(.data.rel.local);
*/
_data.rel.ro = ADDR(.data.rel.ro);
_edata.rel.ro = ADDR(.data.rel.ro) + SIZEOF(.data.rel.ro);
/*
_data.rel.ro.local = ADDR(.data.rel.ro.local);
_edata.rel.ro.local = ADDR(.data.rel.ro.local) + SIZEOF(.data.rel.ro.local);
*/
_dynsym = ADDR(.dynsym);
_edynsym = ADDR(.dynsym) + SIZEOF(.dynsym);
_dynstr = ADDR(.dynstr);
_edynstr = ADDR(.dynstr) + SIZEOF(.dynstr);
/*
_rel = ADDR(.rel);
_erel = ADDR(.rel) + SIZEOF(.rel);
_rela = ADDR(.rela);
_erela = ADDR(.rela) + SIZEOF(.rela);
*/
_dynamic = ADDR(.dynamic);
_edynamic = ADDR(.dynamic) + SIZEOF(.dynamic);
_eh_frame_hdr = ADDR(.eh_frame_hdr);
_eeh_frame_hdr = ADDR(.eh_frame_hdr) + SIZEOF(.eh_frame_hdr);
_eh_frame = ADDR(.eh_frame);
_eeh_frame = ADDR(.eh_frame) + SIZEOF(.eh_frame);
_note_gnu_build_id = ADDR(.note.gnu.build-id);
_enote_gnu_build_id = ADDR(.note.gnu.build-id) + SIZEOF(.note.gnu.build-id);
/DISCARD/ :
{
*(.note.GNU-stack)
*(.GCC.command.line)
*(.gnu.version_d)
*(.gnu.version_r)
*(.gnu.version)
*(.comment)
}
}
/* INSERT BEFORE .note.gnu.build-id; */
INSERT BEFORE .hash;

View file

@ -2,150 +2,269 @@
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
PHDRS
{
load PT_LOAD FLAGS(7);
dynamic PT_DYNAMIC FLAGS(6);
note PT_NOTE FLAGS(4);
stack 7 FLAGS(6);
}
SECTIONS
{
. = 0;
ImageBase = .;
.text 0x2000 : ALIGN(4096)
.text 0x1000 : ALIGN(4096)
{
_start = .;
_text = .;
*(.init)
_start = .;
*(.text)
*(.text.*)
*(.fini)
*(.plt)
*(.plt.got)
*(.gnu.linkonce.t.*)
. = ALIGN(4096);
}
_etext = .;
_text_size = . - _text;
_etext = .;
_text_size = _etext - _text;
} :load
/*
* We have to have a some kind of relocations, or else the loader doesn't
* believe this is position independent, and will try to load us at e.g.
* 0x1000, which will fail.
*/
. = ALIGN(4096);
.reloc :
.reloc ALIGN(4096) : ALIGN(4096)
{
*(.reloc)
}
_reloc = .;
*(.reloc)
_ereloc = .;
_reloc_size = _ereloc - _reloc;
} :load
.data : ALIGN(4096)
.data ALIGN(4096) : ALIGN(4096)
{
_data = .;
*(.data*)
*(.sdata)
*(.srodata*)
*(.rodata*)
*(.got.plt)
*(.got)
_data = .;
*(.data)
*(.data1)
*(.sdata)
*(.got)
*(.got.plt)
. = ALIGN(4096);
_edata = .;
_data_size = _edata - _data;
} :load
/*
* Note that these aren't the using the GNU "CONSTRUCTOR" output section
* command, so they don't start with a size. Because of p2align and the
* end/END definitions, and the fact that they're mergeable, they can also
* have NULLs which aren't guaranteed to be at the end.
*/
. = ALIGN(16);
_init_array = .;
*(SORT_BY_NAME(.init_array))
_init_array_end = .;
__CTOR_LIST__ = .;
*(SORT_BY_NAME(.ctors))
__CTOR_END__ = .;
__DTOR_LIST__ = .;
*(SORT_BY_NAME(.dtors))
__DTOR_END__ = .;
_fini_array = .;
*(SORT_BY_NAME(.fini_array))
_fini_array_end = .;
/* the EFI loader doesn't seem to like a .bss section, so we stick
it all into .data: */
. = ALIGN(4096);
_bss = .;
_bstart = .;
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
. = ALIGN(4096);
_bss_end = .;
_bend = .;
_bsize = _bend - _bstart;
}
.note.gnu.build-id : { *(.note.gnu.build-id) }
.dynamic : ALIGN(512) { *(.dynamic) }
.rela :
.bss ALIGN(4096) (NOLOAD) : ALIGN(4096)
{
*(.rela.dyn)
*(.rela.got)
*(.rela.data)
*(.rela.data*)
*(.rela.plt)
*(.rela.text)
*(.rela.ifunc)
*(.rela.init_array)
*(.rela.fini_array)
*(.data.rela.ro.local)
*(.data.rela.local)
*(.data.rela.ro)
*(.data.rel*)
}
_edata = .;
_data_size = . - _data;
_bss = .;
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
. = ALIGN(4096);
_ebss = .;
_bss_size = _ebss - _bss;
} :load
/*
* We have to have a some kind of relocations, or else the loader doesn't
* believe this is position independent, and will try to load us at e.g.
* 0x1000, which will fail.
*/
. = ALIGN(4096);
.reloc :
.rodata ALIGN(4096) : ALIGN(4096)
{
*(.reloc)
}
_rodata = .;
*(.rodata*)
*(.srodata*)
. = ALIGN(4096);
.hash : ALIGN(1) { *(.hash) }
.gnu.hash : ALIGN(1) { *(.gnu.hash) }
.dynsym : ALIGN(4096) { *(.dynsym) }
.dynstr : ALIGN(4096) { *(.dynstr) }
.eh_frame_hdr : ALIGN(1) { *(.eh_frame_hdr) }
.eh_frame : ALIGN(1) { *(.eh_frame) }
/*
* Note that these aren't the using the GNU "CONSTRUCTOR" output section
* command, so they don't start with a size. Because of p2align and the
* end/END definitions, and the fact that they're mergeable, they can also
* have NULLs which aren't guaranteed to be at the end.
*/
. = ALIGN(16);
_init_array = .;
*(SORT_BY_INIT_PRIORITY(.init_array*))
FILL(0x0);
. = ALIGN(16);
_init_array_end = .;
__CTOR_LIST__ = .;
*(SORT_BY_NAME(.ctors))
FILL(0x0);
. = ALIGN(16);
__CTOR_END__ = .;
__DTOR_LIST__ = .;
*(SORT_BY_NAME(.dtors))
FILL(0x0);
. = ALIGN(16);
__DTOR_END__ = .;
_fini_array = .;
*(SORT_BY_INIT_PRIORITY(.fini_array*))
FILL(0x0);
. = ALIGN(16);
_fini_array_end = .;
. = ALIGN(4096);
_erodata = .;
_rodata_size = _erodata - _rodata;
} :load
.data.rel ALIGN(512) : ALIGN(512)
{
_data_rel = .;
*(.data.rel)
. = ALIGN(512);
_edata_rel = .;
_data_rel_size = _edata_rel - _data_rel;
} :load
.data.rel.local ALIGN(512) : ALIGN(512)
{
_data_rel_local = .;
*(.data.rel.local)
. = ALIGN(512);
_edata_rel_local = .;
_data_rel_local_size = _edata_rel_local - _data_rel_local;
} :load
.data.rel.ro ALIGN(512) : ALIGN(512)
{
_data_rel_ro = .;
*(.data.rel.ro)
. = ALIGN(512);
_edata_rel_ro = .;
_data_rel_ro_size = _edata_rel_ro - _data_rel_ro;
} :load
.data.rel.ro.local ALIGN(512) : ALIGN(512)
{
_data_rel_ro_local = .;
*(.data.rel.ro.local)
. = ALIGN(512);
_edata_rel_ro_local = .;
_data_rel_ro_local_size = _edata_rel_ro_local - _data_rel_ro_local;
} :load
.data.ident ALIGN(512) : ALIGN(512)
{
_data_ident = .;
*(.data.ident)
. = ALIGN(512);
_edata_ident = .;
_data_ident_size = _edata_ident - _data_ident;
} :load =0xa5a5a5a5
.eh_frame_hdr ALIGN(512) : ALIGN(512)
{
_eh_frame_hdr = .;
*(.eh_frame_hdr)
. = ALIGN(512);
_eeh_frame_hdr = .;
_eh_frame_hdr_size = _eeh_frame_hdr - _eh_frame_hdr;
} :load
.eh_frame ALIGN(512) : ALIGN(512)
{
_eh_frame = .;
*(.eh_frame)
. = ALIGN(512);
_eeh_frame = .;
_eh_frame_size = _eeh_frame - _eh_frame;
} :load
.dynamic ALIGN(4096) : ALIGN(4096)
{
_dynamic = .;
*(.dynamic)
. = ALIGN(4096);
_edynamic = .;
_dynamic_size = _edynamic - _dynamic;
} :load
.hash :
{
*(.hash)
} :load
.gnu.hash :
{
*(.gnu.hash)
} :load
.dynstr ALIGN(4096) : ALIGN(4096)
{
_dynstr = .;
*(.dynstr)
. = ALIGN(4096);
_edynstr = .;
_dynstr_size = _edynstr - _dynstr;
} :load
.dynsym ALIGN(4096) : ALIGN(4096)
{
_dynsym = .;
*(.dynsym)
. = ALIGN(4096);
_edynsym = .;
_dynsym_size = _edynsym - _dynsym;
} :load
.rela ALIGN(4096) : ALIGN(4096)
{
_rela = .;
*(.rela)
*(.rela.*)
_erela = .;
_rela_size = _erela - _rela;
} :load
.rel ALIGN(4096) : ALIGN(4096)
{
_rel = .;
*(.rel)
*(.rel.*)
_erel = .;
_rel_size = _erel - _rel;
} :load
.note.gnu.build-id ALIGN(512) : ALIGN(512)
{
_note_gnu_build_id = .;
*(.note.gnu.build-id)
. = ALIGN(512);
_enote_gnu_build_id = .;
_note_gnu_build_id_size = _enote_gnu_build_id - _note_gnu_build_id;
} :load
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* .debug ALIGN(4096) (NOLOAD) : ALIGN(4096) { *(.debug) } :NONE */
/* .line (NOLOAD) : { *(.line) } :NONE */
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* .debug_aranges (NOLOAD) : { *(.debug_aranges) } :NONE */
/* .debug_srcinfo (NOLOAD) : { *(.debug_srcinfo) } :NONE */
/* .debug_sfnames (NOLOAD) : { *(.debug_sfnames) } :NONE */
/* .debug_pubnames (NOLOAD) : { *(.debug_pubnames) } :NONE */
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_macro 0 : { *(.debug_macro*) }
.debug_ranges 0 : { *(.debug_ranges) }
.debug_info (NOLOAD) : { *(.debug_info) } :NONE
.debug_abbrev (NOLOAD) : { *(.debug_abbrev) } :NONE
.debug_aranges (NOLOAD) : { *(.debug_aranges) } :NONE
.debug_ranges (NOLOAD) : { *(.debug_ranges) } :NONE
.debug_line (NOLOAD) : { *(.debug_line) } :NONE
.debug_str (NOLOAD) : { *(.debug_str) } :NONE
.debug_frame (NOLOAD) : { *(.debug_frame) } :NONE
.debug_loc (NOLOAD) : { *(.debug_loc) } :NONE
.debug_macinfo (NOLOAD) : { *(.debug_macinfo) } :NONE
.debug_macro (NOLOAD) : { *(.debug_macro*) } :NONE
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_weaknames (NOLOAD) : { *(.debug_weaknames) } :NONE
.debug_funcnames (NOLOAD) : { *(.debug_funcnames) } :NONE
.debug_typenames (NOLOAD) : { *(.debug_typenames) } :NONE
.debug_varnames (NOLOAD) : { *(.debug_varnames) } :NONE
/DISCARD/ :
{
@ -154,6 +273,6 @@ SECTIONS
*(.gnu.version_d)
*(.gnu.version_r)
*(.gnu.version)
*(.comment)
}
.comment 0 : { *(.comment) }
}

View file

@ -68,10 +68,51 @@ printval_(EFI_SYSTEM_TABLE *systab, int size, uint64_t value)
case 8:
default:
shift = 60;
if (!(value & 0xffffffff00000000ull))
shift >>= 1;
break;
}
// value = 0x00000070
// shift = 12
// i = 16
// mask = ~((1<<16)-1) = ~(0x10000-1) = ~0xffff = 0xffff0000
// mask & value = 0x00000000
// i = 12
// mask = ~((1<<12)-1) = ~(0x1000-1) = ~0xfff = 0xfffff000
// mask & value = 0x00000000
// i = 8
// mask = ~((1<<8)-1) = ~(0x100-1) = ~0xff = 0xffffff00
// mask & value = 0x00000000
// i = 4
// mask = ~((1<<4)-1) = ~(0x10-1) = ~0xf = 0xfffffff0
// mask & value = 0x000000b0
// i = 8
// break
for (i = shift + 4; i > 4; i -= 4) {
mask = ~((1 << i) - 1);
if (value & mask) {
i += 4;
break;
}
}
shift = i;
#if 0
if (!(value & 0xffffffffffffff00ull) && shift > 4)
shift = 4;
else if (!(value & 0xffffffffffff0000ull) && shift > 12)
shift = 12;
else if (!(value & 0xffffffffff000000ull) && shift > 20)
shift = 20;
else if (!(value & 0xffffffff00000000ull) && shift > 28)
shift = 28;
else if (!(value & 0xffffff0000000000ull) && shift > 36)
shift = 36;
else if (!(value & 0xffff000000000000ull) && shift > 44)
shift = 44;
else if (!(value & 0xff00000000000000ull) && shift > 52)
shift = 52;
#endif
mask = 0xfull << shift;
for (i = 2; mask != 0; i += 2) {
@ -94,92 +135,321 @@ print_(EFI_SYSTEM_TABLE *systab, wchar_t *str)
systab->ConOut->OutputString(systab->ConOut, str);
}
#if 0
#define _STRING(x) #x
#define STRING(x) _STRING(x)
#define CONCAT(x,y) x ## y
#define STARTSTOP(x,y) \
".weakref _" STRING(x) ", _start_." STRING(y) "\n" \
".weakref _e" STRING(x) ", _stop_." STRING(y) "\n"
__asm__ (
STARTSTOP(text, text)
STARTSTOP(reloc, reloc)
STARTSTOP(data, data)
STARTSTOP(bss, bss)
STARTSTOP(rodata, rodata)
STARTSTOP(data_rel, data.rel)
STARTSTOP(data_rel_local, data.rel.local)
STARTSTOP(data_rel_ro, data.rel.ro)
STARTSTOP(data_rel_ro_local, data.rel.ro.local)
STARTSTOP(data_rela, data.rela)
STARTSTOP(data_rela_local, data.rela.local)
STARTSTOP(data_rela_ro, data.rela.ro)
STARTSTOP(data_rela_ro_local, data.rela.ro.local)
STARTSTOP(dynsym, dynsym)
STARTSTOP(dynstr, dynstr)
STARTSTOP(rel, rel)
STARTSTOP(rela, rela)
STARTSTOP(dynamic, dynamic)
STARTSTOP(eh_frame_hdr, eh_frame_hdr)
STARTSTOP(eh_frame, eh_frame)
);
#endif
extern uint8_t
_text, _etext,
_reloc, _ereloc,
_data, _edata,
_bss, _ebss,
_rodata, _erodata,
#if 0
_data_rel, _edata_rel,
_data_rel_local, _edata_rel_local,
_data_rel_ro, _edata_rel_ro,
_data_rel_ro_local, _edata_rel_ro_local,
#endif
_dynsym, _edynsym,
_dynstr, _edynstr,
#if 0
_data_ident, _edata_ident,
_rel, _erel,
_rela, _erela,
#endif
_dynamic, _edynamic,
_note_gnu_build_id, _enote_gnu_build_id,
_eh_frame_hdr, _eeh_frame_hdr,
_eh_frame, _eeh_frame
;
static struct {
void *begin;
void *end;
wchar_t name[32];
} _sections[] = {
{ &_text, &_etext, L".text" },
{ &_reloc, &_ereloc, L".relocl" },
{ &_data, &_edata, L".data" },
{ &_bss, &_ebss, L".bss" },
{ &_rodata, &_erodata, L".rodata" },
#if 0
{ &_data_rel, &_edata_rel, L".data.rel" },
{ &_data_rel_local, &_edata_rel_local, L".data.rel.local" },
{ &_data_rel_ro, &_edata_rel_ro, L".data.rel.ro" },
{ &_data_rel_ro_local, &_edata_rel_ro_local, L".data.rel.ro.local" },
#endif
{ &_dynsym, &_edynsym, L".dynsym" },
{ &_dynstr, &_edynstr, L".dynstr" },
#if 0
{ &_data_ident, &_edata_ident, L".data.ident" },
{ &_rel, &_erel, L".rel" },
{ &_rela, &_erela, L".rela" },
#endif
{ &_dynamic, &_edynamic, L".dynamic" },
{ &_note_gnu_build_id, &_enote_gnu_build_id, L".note.gnu.build-id" },
{ &_eh_frame_hdr, &_eeh_frame_hdr, L".eh_frame_hdr" },
{ &_eh_frame, &_eeh_frame, L".eh_frame" },
{ NULL, NULL, L"" }
};
static void
__attribute__((__unused__))
printsection_(EFI_SYSTEM_TABLE *systab, uint64_t addr)
{
unsigned int i;
void *obj = (void *)addr;
for (i = 0; _sections[i].name[0] != L'\0'; i++) {
if (_sections[i].begin >= obj && _sections[i].end <= obj) {
print_(systab, _sections[i].name);
return;
}
}
print_(systab, L"unknown section");
}
#ifdef EFI_DEBUG
#define printval(a) printval_(systab, sizeof(a), (uint64_t)(a))
#define print(x) print_(systab, (x))
#define printsection(obj) printsection_(systab, obj)
#else
#define printval(a)
#define print(x)
#define printsection(obj)
#endif
extern uint8_t _bstart, _bend;
extern uint8_t ImageBase;
EFI_STATUS _relocate (unsigned long ldbase, Elf64_Dyn *dyn,
EFI_HANDLE image EFI_UNUSED,
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
EFI_STATUS EFIAPI _relocate (unsigned long ldbase, Elf64_Dyn *dyn,
EFI_HANDLE image EFI_UNUSED,
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
{
long relsz = 0, relent = 0;
Elf64_Rela *rela = 0;
uint64_t relasz = 0, relaent = 0;
uint64_t relsz = 0, relent = 0;
Elf64_Rel *rel = 0;
unsigned long *addr = NULL;
int i;
print(L"ldbase:"); printval(ldbase);
print(L" dyn:"); printval(dyn); print(L"\r\n");
print(L" ldbase:"); printval(ldbase);
print(L" dyn:"); printval(dyn);
print(L" img:"); printval(image);
print(L" systab:"); printval(systab);
print(L"\r\n");
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
print(L"i:"); printval(i);
print(L" tag:"); printval(dyn[i].d_tag);
print(L" ");
switch (dyn[i].d_tag) {
case DT_NULL: print(L"DT_NULL"); break;
case DT_NEEDED: print(L"DT_NEEDED:\t"); printval(dyn[i].d_un.d_val); break;
case DT_PLTRELSZ: print(L"DT_PLTRELSZ:\t"); printval(dyn[i].d_un.d_val); break;
case DT_PLTGOT: print(L"DT_PLTGOT:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_HASH: print(L"DT_HASH:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_STRTAB: print(L"DT_STRTAB:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_SYMTAB: print(L"DT_SYMTAB:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_NULL:
print(L"DT_NULL");
break;
case DT_NEEDED:
print(L"DT_NEEDED: ");
printval(dyn[i].d_un.d_val);
break;
case DT_PLTRELSZ:
print(L"DT_PLTRELSZ: ");
printval(dyn[i].d_un.d_val);
break;
case DT_PLTGOT:
print(L"DT_PLTGOT: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_HASH:
print(L"DT_HASH: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_STRTAB:
print(L"DT_STRTAB: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_SYMTAB:
print(L"DT_SYMTAB: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_RELA:
rela = (Elf64_Rela*)
((unsigned long)dyn[i].d_un.d_ptr
+ ldbase);
print(L"DT_RELA: ");
printval((unsigned long)dyn[i].d_un.d_ptr);
print(L"+ldbase->");
printval(rela);
break;
case DT_RELASZ:
relasz = dyn[i].d_un.d_val;
print(L"DT_RELASZ: ");
printval(relasz);
break;
case DT_RELAENT:
relaent = dyn[i].d_un.d_val;
print(L"DT_RELAENT: ");
printval(relaent);
break;
case DT_STRSZ:
print(L"DT_STRSZ: ");
printval(dyn[i].d_un.d_val);
break;
case DT_SYMENT:
print(L"DT_SYMENT: ");
printval(dyn[i].d_un.d_val);
break;
case DT_INIT:
print(L"DT_INIT: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_FINI:
print(L"DT_FINI: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_SONAME:
print(L"DT_SONAME: ");
printval(dyn[i].d_un.d_val);
break;
case DT_RPATH:
print(L"DT_RPATH: ");
printval(dyn[i].d_un.d_val);
break;
case DT_SYMBOLIC:
print(L"DT_SYMBOLIC");
break;
case DT_REL:
rel = (Elf64_Rel*)
((unsigned long)dyn[i].d_un.d_ptr
+ ldbase);
print(L"DT_RELA:\t"); printval(rel);
print(L"DT_REL: ");
printval((unsigned long)dyn[i].d_un.d_ptr);
print(L"+ldbase->");
printval(rel);
break;
case DT_RELASZ:
case DT_RELSZ:
relsz = dyn[i].d_un.d_val;
print(L"DT_RELASZ:\t"); printval(relsz);
print(L"DT_RELSZ: ");
printval(relsz);
break;
case DT_RELAENT:
case DT_RELENT:
relent = dyn[i].d_un.d_val;
print(L"DT_RELAENT:\t"); printval(relent);
print(L"DT_RELENT: ");
printval(relent);
break;
case DT_PLTREL:
print(L"DT_PLTREL: ");
printval(dyn[i].d_un.d_val);
break;
case DT_DEBUG:
print(L"DT_DEBUG: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_TEXTREL:
print(L"DT_TEXTREL");
break;
case DT_JMPREL:
print(L"DT_JMPREL: ");
printval(dyn[i].d_un.d_ptr);
break;
case DT_BIND_NOW:
print(L"DT_BIND_NOW");
break;
case DT_LOPROC:
print(L"DT_LOPROC: ");
printval((uint32_t)0x70000000u);
break;
case DT_HIPROC:
print(L"DT_HIPROC: ");
printval((uint32_t)0x7fffffffu);
break;
case DT_STRSZ: print(L"DT_STRSZ:\t"); printval(dyn[i].d_un.d_val); break;
case DT_SYMENT: print(L"DT_SYMENT:\t"); printval(dyn[i].d_un.d_val); break;
case DT_INIT: print(L"DT_INIT:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_FINI: print(L"DT_FINI:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_SONAME: print(L"DT_SONAME:\t"); printval(dyn[i].d_un.d_val); break;
case DT_RPATH: print(L"DT_RPATH:\t"); printval(dyn[i].d_un.d_val); break;
case DT_SYMBOLIC: print(L"DT_SYMBOLIC"); break;
case DT_REL: print(L"DT_REL:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_RELSZ: print(L"DT_RELSZ:\t"); printval(dyn[i].d_un.d_val); break;
case DT_RELENT: print(L"DT_RELENT:\t"); printval(dyn[i].d_un.d_val); break;
case DT_PLTREL: print(L"DT_PLTREL:\t"); printval(dyn[i].d_un.d_val); break;
case DT_DEBUG: print(L"DT_DEBUG:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_TEXTREL: print(L"DT_TEXTREL"); break;
case DT_JMPREL: print(L"DT_JMPREL:\t"); printval(dyn[i].d_un.d_ptr); break;
case DT_BIND_NOW: print(L"DT_BIND_NOW"); break;
case DT_LOPROC: print(L"DT_LOPROC:\t"); printval((uint32_t)0x70000000u); break;
case DT_HIPROC: print(L"DT_HIPROC:\t"); printval((uint32_t)0x7fffffffu); break;
default:
print(L"UNKNOWN:\t");
print(L"UNKNOWN: ");
printval(dyn[i].d_un.d_val);
break;
}
print(L"\r\n");
}
if (!rel && relent == 0) {
print(L"!rel && relent == 0\r\n");
return EFI_SUCCESS;
if (!rel && !rela && relent == 0 && relaent == 0) {
print(L"!rela && relaent == 0 && !rel && relent == 0\r\n");
return EFI_SUCCESS;
}
if (!rel || relent == 0) {
print(L"!rel || relent == 0\r\n");
if ((!rel || relent == 0) && (!rela || relaent == 0)) {
if (!rela && relaent == 0)
print(L"!rela || relaent == 0\r\n");
if (!rel && relent == 0)
print(L"!rel || relent == 0\r\n");
return EFI_LOAD_ERROR;
}
while (relasz > 0) {
/* apply the relocs */
switch (ELF64_R_TYPE (rela->r_info)) {
case R_X86_64_NONE:
addr = (unsigned long *)
(ldbase + rela->r_offset);
print(L"NONE");
print(L" offset:"); printval(rela->r_offset);
print(L" *rela:"); printval(*addr);
print(L" +addend:"); printval(rela->r_addend);
print(L" "); printsection(*addr);
break;
case R_X86_64_RELATIVE:
addr = (unsigned long *)
(ldbase + rela->r_offset);
print(L"RELA");
print(L" offset:"); printval(rela->r_offset);
print(L" *rela:"); printval(*addr);
print(L" +addend:"); printval(rela->r_addend);
print(L"->");
*addr += ldbase;
*addr += rela->r_addend;
printval(*addr);
print(L" "); printsection(*addr - ldbase);
break;
default:
print(L"???? tag:");
printval(dyn[i].d_tag);
print(L" offset:");
printval(rela->r_offset);
print(L" "); printsection(rela->r_offset);
break;
}
print(L"\r\n");
rela = (Elf64_Rela*) ((char *) rela + relaent);
relasz -= relaent;
}
while (relsz > 0) {
/* apply the relocs */
switch (ELF64_R_TYPE (rel->r_info)) {
@ -189,17 +459,19 @@ EFI_STATUS _relocate (unsigned long ldbase, Elf64_Dyn *dyn,
print(L"NONE");
print(L" offset:"); printval(rel->r_offset);
print(L" *rel:"); printval(*addr);
print(L" "); printsection(*addr);
break;
case R_X86_64_RELATIVE:
addr = (unsigned long *)
(ldbase + rel->r_offset);
print(L"RELA");
print(L"REL");
print(L" offset:"); printval(rel->r_offset);
print(L" *rel:"); printval(*addr);
print(L"->");
*addr += ldbase;
printval(*addr);
print(L" "); printsection(*addr - ldbase);
break;
default:
@ -207,6 +479,7 @@ EFI_STATUS _relocate (unsigned long ldbase, Elf64_Dyn *dyn,
printval(dyn[i].d_tag);
print(L" offset:");
printval(rel->r_offset);
print(L" "); printsection(rel->r_offset);
break;
}
print(L"\r\n");
@ -214,11 +487,11 @@ EFI_STATUS _relocate (unsigned long ldbase, Elf64_Dyn *dyn,
relsz -= relent;
}
print(L"zeroing ");
printval(&_bstart - &_bend);
printval(&_ebss - &_bss);
print(L" bytes of .bss at ");
printval(&_bstart);
printval(&_bss);
print(L"\r\n");
ZeroMem(&_bstart, &_bend - &_bstart);
ZeroMem(&_bss, &_ebss - &_bss);
print(L"returning success\r\n");
return EFI_SUCCESS;

View file

@ -75,10 +75,11 @@ _EFI_CCLDLIBS = $(subst $(_efi_space),$(_efi_comma),-Wl --start-group $(foreach
EFI_BIN_SECTIONS ?= .text .sdata .data .dynamic .dynsym \
.rel .rel.* .rela .rela.* .reloc \
.eh_frame .note.gnu.build-id .ctf \
.eh_frame* .note.gnu.build-id .ctf \
.debug* \
$(EFI_ARCH_BIN_SECTIONS)
EFI_DEBUG_SECTIONS ?= .debug* .eh_frame .note.gnu.build-id .ctf \
EFI_DEBUG_SECTIONS ?= .debug* .eh_frame* .note.gnu.build-id .ctf \
$(EFI_ARCH_DEBUG_SECTIONS)
EFI_OBJCOPY_FLAGS ?= --file-alignment 512 --section-alignment 4096 -D
@ -87,7 +88,7 @@ ifneq ($(EFI_OBJCOPY_GTE224),1)
$(error objcopy >= 2.24 is required)
endif
$(OBJCOPY) $(EFI_OBJCOPY_FLAGS) \
$(foreach x,$(EFI_BIN_SECTIONS),-j $(x)) \
$(foreach x,$(EFI_BIN_SECTIONS),-j "$(x))" \
$(EFI_ARCH_FORMAT) $*.efi.so $@
%.efi.debug : %.efi.so
@ -95,7 +96,7 @@ ifneq ($(EFI_OBJCOPY_GTE224),1)
$(error objcopy >= 2.24 is required)
endif
$(OBJCOPY) $(EFI_OBJCOPY_FLAGS) \
$(foreach x,$(EFI_DEBUG_SECTIONS),-j $(x)) \
$(foreach x,$(EFI_DEBUG_SECTIONS),-j "$(x)") \
$(EFI_ARCH_FORMAT) $*.efi.so $@
%.efi.a :

View file

@ -981,7 +981,7 @@ _DevPathFilePath (
Print(L"%a:%d Fp:%xh\n", __FILE__, __LINE__, Fp);
Print(L"%a:%d Fp->PathName:%xh\n", __FILE__, __LINE__, Fp->PathName);
CatPrint(Str, L"%s", Fp->PathName);
Print(L"%a:%d\n", __FILE__, __LINE__);
Print(L"%a:%d Str:\"%s\"\n", __FILE__, __LINE__, Str);
}
static VOID
@ -1140,16 +1140,13 @@ DevicePathToStr (
VOID (*DumpNode)(POOL_PRINT *, VOID *);
UINTN Index, NewSize;
Print(L"%a:%d\n", __FILE__, __LINE__);
ZeroMem(&Str, sizeof(Str));
//
// Unpacked the device path
//
Print(L"%a:%d\n", __FILE__, __LINE__);
DevPath = UnpackDevicePath(DevPath);
Print(L"%a:%d\n", __FILE__, __LINE__);
ASSERT (DevPath);
@ -1158,21 +1155,17 @@ DevicePathToStr (
//
DevPathNode = DevPath;
Print(L"%a:%d\n", __FILE__, __LINE__);
while (!IsDevicePathEnd(DevPathNode)) {
Print(L"%a:%d\n", __FILE__, __LINE__);
//
// Find the handler to dump this device path node
//
DumpNode = NULL;
for (Index = 0; DevPathTable[Index].Function; Index += 1) {
Print(L"%a:%d\n", __FILE__, __LINE__);
if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
DumpNode = DevPathTable[Index].Function;
Print(L"%a:%d,idx=%d DumpNode:%xh\n", __FILE__, __LINE__, Index, DumpNode);
break;
}
}
@ -1182,7 +1175,6 @@ DevicePathToStr (
//
if (!DumpNode) {
Print(L"%a:%d\n", __FILE__, __LINE__);
DumpNode = _DevPathNodeUnknown;
}
@ -1191,7 +1183,6 @@ DevicePathToStr (
//
if (Str.len && DumpNode != _DevPathEndInstance) {
Print(L"%a:%d\n", __FILE__, __LINE__);
CatPrint (&Str, L"/");
}
@ -1199,31 +1190,23 @@ DevicePathToStr (
// Print this node of the device path
//
Print(L"%a:%d\n", __FILE__, __LINE__);
DumpNode (&Str, DevPathNode);
//
// Next device path node
//
Print(L"%a:%d\n", __FILE__, __LINE__);
DevPathNode = NextDevicePathNode(DevPathNode);
Print(L"%a:%d\n", __FILE__, __LINE__);
}
//
// Shrink pool used for string allocation
//
Print(L"%a:%d\n", __FILE__, __LINE__);
FreePool (DevPath);
Print(L"%a:%d\n", __FILE__, __LINE__);
NewSize = (Str.len + 1) * sizeof(CHAR16);
Print(L"%a:%d\n", __FILE__, __LINE__);
Str.str = ReallocatePool (Str.str, NewSize, NewSize);
Print(L"%a:%d\n", __FILE__, __LINE__);
Str.str[Str.len] = 0;
Print(L"%a:%d\n", __FILE__, __LINE__);
return Str.str;
}