Skip to content

Commit

Permalink
More explicit link type handling
Browse files Browse the repository at this point in the history
  • Loading branch information
fuhsnn committed Feb 20, 2025
1 parent 903607e commit 66beb19
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 54 deletions.
14 changes: 14 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,20 @@ static FileType get_file_type(char *filename) {
error("<command line>: unknown file extension: %s", filename);
}

LinkType get_link_type(void) {
if (opt_r)
return LT_RELO;
if (opt_shared)
return LT_SHARED;
if (opt_static_pie)
return LT_STATIC_PIE;
if (opt_static)
return LT_STATIC;
if (opt_pie)
return LT_PIE;
return LT_DYNAMIC;
}

int main(int argc, char **argv) {
atexit(cleanup);
init_macros();
Expand Down
85 changes: 54 additions & 31 deletions platform/linux-generic-glibc-intree.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ void platform_init(void) {

init_ty(ty_ulong, ty_long, ty_long);

set_pic("2", true);
opt_pie = true;
// set_pic("2", true);
//opt_pie = true;
}

static char *find_file(char *pattern) {
Expand All @@ -34,7 +34,7 @@ void add_default_include_paths(StringArray *paths, char *argv0) {

// Add standard include paths.
strarray_push(paths, "/usr/local/include");
strarray_push(paths, "/usr/include/x86_64-linux-gnu");
// strarray_push(paths, "/usr/include/x86_64-linux-gnu");
strarray_push(paths, "/usr/include");

for (int i = 0; i < paths->len; i++)
Expand Down Expand Up @@ -92,38 +92,60 @@ void run_linker(StringArray *extra_args, StringArray *inputs, char *output) {
strarray_push(&arr, "-m");
strarray_push(&arr, "elf_x86_64");

strarray_push(&arr, "--eh-frame-hdr");
LinkType type = get_link_type();

if (opt_r) {
switch (type) {
case LT_RELO:
strarray_push(&arr, "-r");
} else if (opt_shared) {
break;
case LT_SHARED:
strarray_push(&arr, "-shared");
} else if (opt_static_pie) {
break;
case LT_STATIC_PIE:
strarray_push(&arr, "-static");
strarray_push(&arr, "-pie");
} else if (opt_static) {
break;
case LT_STATIC:
strarray_push(&arr, "-static");
} else if (opt_pie) {
break;
case LT_PIE:
strarray_push(&arr, "-pie");
break;
}

switch (type) {
case LT_STATIC_PIE:
strarray_push(&arr, "-no-dynamic-linker");
break;
case LT_DYNAMIC:
case LT_SHARED:
case LT_PIE:
if (opt_rdynamic)
strarray_push(&arr, "-export-dynamic");

strarray_push(&arr, "-dynamic-linker");
strarray_push(&arr, "/lib64/ld-linux-x86-64.so.2");
}

if (!(opt_nostartfiles || opt_r)) {
if (opt_shared) {
strarray_push(&arr, "--eh-frame-hdr");

if (!opt_nostartfiles && type != LT_RELO) {
if (type == LT_SHARED) {
strarray_push(&arr, format("%s/crti.o", libpath()));
strarray_push(&arr, format("%s/crtbeginS.o", gcc_libpath()));
} else if (opt_static_pie) {
} else if (type == LT_STATIC_PIE) {
strarray_push(&arr, format("%s/rcrt1.o", libpath()));
strarray_push(&arr, format("%s/crti.o", libpath()));
strarray_push(&arr, format("%s/crtbeginS.o", gcc_libpath()));
} else if (opt_static) {
} else if (type == LT_STATIC) {
strarray_push(&arr, format("%s/crt1.o", libpath()));
strarray_push(&arr, format("%s/crti.o", libpath()));
strarray_push(&arr, format("%s/crtbeginT.o", gcc_libpath()));
} else if (opt_pie) {
} else if (type == LT_PIE) {
strarray_push(&arr, format("%s/Scrt1.o", libpath()));
strarray_push(&arr, format("%s/crti.o", libpath()));
strarray_push(&arr, format("%s/crtbeginS.o", gcc_libpath()));
} else {
} else if (type == LT_DYNAMIC) {
strarray_push(&arr, format("%s/crt1.o", libpath()));
strarray_push(&arr, format("%s/crti.o", libpath()));
strarray_push(&arr, format("%s/crtbegin.o", gcc_libpath()));
Expand All @@ -145,45 +167,46 @@ void run_linker(StringArray *extra_args, StringArray *inputs, char *output) {
strarray_push(&arr, "-L/lib");
}

if (opt_static || opt_static_pie || opt_r) {
strarray_push(&arr, "-no-dynamic-linker");
} else {
if (opt_rdynamic)
strarray_push(&arr, "-export-dynamic");

strarray_push(&arr, "-dynamic-linker");
strarray_push(&arr, "/lib64/ld-linux-x86-64.so.2");
}

for (int i = 0; i < inputs->len; i++)
strarray_push(&arr, inputs->data[i]);

if (!(opt_nodefaultlibs || opt_r)) {
if (!opt_nodefaultlibs && type != LT_RELO) {
if (opt_pthread)
strarray_push(&arr, "-lpthread");

if (opt_static || opt_static_pie) {
if (type == LT_STATIC_PIE || type == LT_STATIC) {
strarray_push(&arr, "--start-group");
strarray_push(&arr, "-lgcc");
strarray_push(&arr, "-lgcc_eh");
if (!opt_nolibc)
strarray_push(&arr, "-lc");
strarray_push(&arr, "--end-group");
} else {
strarray_push(&arr, "-lgcc");
strarray_push(&arr, "--push-state");
strarray_push(&arr, "--as-needed");
strarray_push(&arr, "-lgcc_s");
strarray_push(&arr, "--pop-state");
if (!opt_nolibc)
strarray_push(&arr, "-lc");
strarray_push(&arr, "-lgcc");
strarray_push(&arr, "--push-state");
strarray_push(&arr, "--as-needed");
strarray_push(&arr, "-lgcc_s");
strarray_push(&arr, "--no-as-needed");
strarray_push(&arr, "--pop-state");
}
}

if (!(opt_nostartfiles || opt_r)) {
if (opt_shared || opt_pie || opt_static_pie)
if (!opt_nostartfiles && type != LT_RELO) {
switch (type) {
case LT_STATIC_PIE:
case LT_SHARED:
case LT_PIE:
strarray_push(&arr, format("%s/crtendS.o", gcc_libpath()));
else
break;
default:
strarray_push(&arr, format("%s/crtend.o", gcc_libpath()));
}

strarray_push(&arr, format("%s/crtn.o", libpath()));
}
Expand Down
57 changes: 34 additions & 23 deletions platform/linux-musl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "slimcc.h"

#define MUSLPATH
#if !defined(MUSLPATH)
#error
#endif
Expand Down Expand Up @@ -56,23 +56,45 @@ void run_linker(StringArray *extra_args, StringArray *inputs, char *output) {
strarray_push(&arr, "-m");
strarray_push(&arr, "elf_x86_64");

if (opt_r) {
LinkType type = get_link_type();

switch (type) {
case LT_RELO:
strarray_push(&arr, "-r");
} else if (opt_shared) {
break;
case LT_SHARED:
strarray_push(&arr, "-shared");
} else if (opt_static_pie) {
break;
case LT_STATIC_PIE:
strarray_push(&arr, "-static");
strarray_push(&arr, "-pie");
} else if (opt_static) {
break;
case LT_STATIC:
strarray_push(&arr, "-static");
} else if (opt_pie) {
break;
case LT_PIE:
strarray_push(&arr, "-pie");
break;
}

switch (type) {
case LT_STATIC_PIE:
strarray_push(&arr, "-no-dynamic-linker");
break;
case LT_DYNAMIC:
case LT_SHARED:
case LT_PIE:
if (opt_rdynamic)
strarray_push(&arr, "-export-dynamic");

strarray_push(&arr, "-dynamic-linker");
strarray_push(&arr, MUSLPATH"/lib/libc.so");
}

if (!(opt_nostartfiles || opt_r)) {
if (opt_static_pie)
if (!opt_nostartfiles && type != LT_RELO) {
if (type == LT_STATIC_PIE)
strarray_push(&arr, MUSLPATH"/lib/rcrt1.o");
else if (opt_pie)
else if (type == LT_PIE)
strarray_push(&arr, MUSLPATH"/lib/Scrt1.o");
else
strarray_push(&arr, MUSLPATH"/lib/crt1.o");
Expand All @@ -83,31 +105,20 @@ void run_linker(StringArray *extra_args, StringArray *inputs, char *output) {
for (int i = 0; i < extra_args->len; i++)
strarray_push(&arr, extra_args->data[i]);

if (!opt_nodefaultlibs) {
if (!opt_nodefaultlibs)
strarray_push(&arr, ("-L"MUSLPATH"/lib"));
}

if (opt_static || opt_static_pie || opt_r) {
strarray_push(&arr, "-no-dynamic-linker");
} else {
if (opt_rdynamic)
strarray_push(&arr, "-export-dynamic");

strarray_push(&arr, "-dynamic-linker");
strarray_push(&arr, MUSLPATH"/lib/libc.so");
}

for (int i = 0; i < inputs->len; i++)
strarray_push(&arr, inputs->data[i]);

if (!(opt_nodefaultlibs || opt_r)) {
if (!opt_nodefaultlibs && type != LT_RELO) {
if (opt_pthread)
strarray_push(&arr, "-lpthread");
if (!opt_nolibc)
strarray_push(&arr, "-lc");
}

if (!(opt_nostartfiles || opt_r))
if (!opt_nostartfiles && type != LT_RELO)
strarray_push(&arr, MUSLPATH"/lib/crtn.o");

strarray_push(&arr, NULL);
Expand Down
12 changes: 12 additions & 0 deletions slimcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,3 +704,15 @@ void add_default_include_paths(StringArray *paths, char *argv0);
void run_assembler(StringArray *as_args, char *input, char *output);
void run_linker(StringArray *extra_args, StringArray *inputs, char *output);
void platform_init(void);

typedef enum {
LT_DEFAULT,
LT_RELO,
LT_SHARED,
LT_DYNAMIC,
LT_STATIC_PIE,
LT_STATIC,
LT_PIE,
} LinkType;

LinkType get_link_type(void);

0 comments on commit 66beb19

Please sign in to comment.