summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2019-07-27 13:27:39 -0700
committerH. Peter Anvin <hpa@zytor.com>2019-07-27 13:27:39 -0700
commit94163d75874506496da636153fefc672e2f7b75f (patch)
tree15f6363735c7ad3682b538558d5de99b326aa224
parent110633af87084b289d6eeda0626fcb5645edfc60 (diff)
downloadsamples-94163d75874506496da636153fefc672e2f7b75f.tar.gz
samples-94163d75874506496da636153fefc672e2f7b75f.tar.xz
samples-94163d75874506496da636153fefc672e2f7b75f.zip
Make -pie linking actually work; use ___start for initial symbol
-rw-r--r--Makefile6
-rw-r--r--com.ld4
-rw-r--r--exe.ld51
-rw-r--r--testme.s6
4 files changed, 47 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 4d95bef..5425d04 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ AS = $(CROSS)as
ASFLAGS = --32
LD = $(CROSS)ld
-LDFLAGS = -m elf_i386 -q -z max-page-size=16
+LDFLAGS = -m elf_i386 -q -z max-page-size=16 --hash-style=gnu
OBJCOPY = $(CROSS)objcopy
@@ -20,10 +20,10 @@ ALL = testme.exe.elf testme.com.elf testme.com # testme.exe
all: $(ALL)
%.exe.elf: $(OBJS) exe.ld
- $(LD) $(LDFLAGS) -Map=$*.map -T exe.ld -o $@ $(OBJS)
+ $(LD) $(LDFLAGS) -pie -Map=$*.exe.map -T exe.ld -o $@ $(OBJS)
%.com.elf: $(OBJS) com.ld
- $(LD) $(LDFLAGS) -Map=$*.map -T com.ld -o $@ $(OBJS)
+ $(LD) $(LDFLAGS) -Map=$*.com.map -T com.ld -o $@ $(OBJS)
%.com: %.com.elf
$(OBJCOPY) -O binary $< $@
diff --git a/com.ld b/com.ld
index 9adec9c..19c7bb2 100644
--- a/com.ld
+++ b/com.ld
@@ -1,12 +1,13 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i8086)
-ENTRY(__start)
+ENTRY(___start)
SECTIONS
{
. = 0;
DGROUP (NOLOAD) : {
*(*!*)
+ PROVIDE(___start! = .);
PROVIDE(__psp! = .);
PROVIDE(___bss_start! = .);
PROVIDE(___bss_end! = .);
@@ -21,6 +22,7 @@ SECTIONS
}
_TEXT : {
+ PROVIDE(___start = .); /* Overridable default */
*(SORT_NONE(_START*))
*(SORT_BY_ALIGNMENT(_TEXT*) SORT_BY_ALIGNMENT(.text*))
}
diff --git a/exe.ld b/exe.ld
index e03e0fe..9fa387e 100644
--- a/exe.ld
+++ b/exe.ld
@@ -1,6 +1,6 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i8086)
-ENTRY(__start)
+ENTRY(___start)
SECTIONS
{
/*
@@ -29,6 +29,10 @@ SECTIONS
}
_TEXT ALIGN(16) : {
+ /* Overridable default for __start */
+ PROVIDE(___start! = .);
+ PROVIDE(___start = .);
+
*(_START*!* _TEXT*!*)
*(SORT_NONE(_START*))
*(SORT_BY_ALIGNMENT(_TEXT*) SORT_BY_ALIGNMENT(.text*))
@@ -67,9 +71,9 @@ SECTIONS
/* Default near stack/heap segment size, can be overridden */
PROVIDE(___stack_size = 65536 + ADDR(DGROUP) - .);
_STACK (NOLOAD) : {
- PROVIDE(___stack_base = .);
+ PROVIDE(___stack_start = .);
. = . + ___stack_size;
- PROVIDE(___stack_top = .);
+ PROVIDE(___stack_end = .);
}
far_BSS ALIGN(16) : {
@@ -79,17 +83,33 @@ SECTIONS
}
PROVIDE(___end = .);
+ HIDDEN(___.end = .);
- /* For PIE linking */
- .dynamic : AT(___.filesize) {
- PROVIDE(___DYNAMIC = .);
- *(.dynamic)
+ /*
+ * Anything beyond this point is used by elf2exe and are not
+ * part of the final output. However, the linker loudly
+ * objects if the dynamic section is not part of a loadable
+ * segment, so we remove it in postprocessing.
+ */
+ .exeinfo : {
+ LONG(0x05806870); /* Magic number */
+ LONG(___.filesize); /* True file size */
+ LONG(___.end); /* True emory size */
+ /* SEG:OFF forms of ___start and ___stack_top */
+ SHORT(___start - "___start!");
+ SHORT("___start!");
+ SHORT(___stack_end - "___stack_end!");
+ SHORT("___stack_end!");
}
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .hash : { *(.hash) }
- .gnu.hash : { *(.gnu.hash) }
- .rel.dyn : { *(.rel*) }
+
+ /* PIE linking: give us all the dynamic data including relocations */
+ .dynamic : { KEEP(*(.dynamic)) }
+ .dynsym : { KEEP(*(.dynsym)) }
+ .dynstr : { KEEP(*(.dynstr)) }
+ .gnu.hash : { KEEP(*(.gnu.hash)) }
+ .rel.dyn : { KEEP(*(.rel*)) }
+
+ HIDDEN(___.header_end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
@@ -132,5 +152,10 @@ SECTIONS
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.gnu_debuglink)
+ *(.gnu.lto_*)
+ *(.hash)
+ }
}
diff --git a/testme.s b/testme.s
index fbe65b1..3fcec83 100644
--- a/testme.s
+++ b/testme.s
@@ -14,9 +14,9 @@
.section "_TEXT$","ax"
.L_SEG = .SEG._TEXT
- .globl __start, "__start!"
- .equ "__start!", .L.SEG
-__start:
+ .globl ___start, "___start!"
+ .equ "___start!", .L.SEG
+___start:
mov $0,%ax
.reloc .-2, R_386_SEG16, .SEG.DGROUP
mov %ax,%ds