Skip to content

Commit

Permalink
Revamp efi_well_known_* variable handling
Browse files Browse the repository at this point in the history
The current implementation attempts to use the linker to create aliases
for efi_well_known_guids and efi_well_known_names. It also tries to use
the linker to generate the variables efi_well_known_guids_end and
efi_well_known_names_end.

When building with clang, the generated linker result results in a
broken libefivar.so that causes programs to segfault when linked against
it.  This change does away with linker script hacker and instead
introduces pointers to store the locations of efi_well_known_guids_end
and efi_well_known_names_end.

Additionally, efi_well_known_guids and efi_well_known_names are now
created as pointers that point to the beginning of their respective
arrays.

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Fixes: #234
  • Loading branch information
nvinson authored and frozencemetery committed Feb 6, 2023
1 parent 914c686 commit cfd686d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 81 deletions.
7 changes: 2 additions & 5 deletions src/Makefile
Expand Up @@ -4,7 +4,6 @@ include $(TOPDIR)/src/include/deprecated.mk
include $(TOPDIR)/src/include/version.mk
include $(TOPDIR)/src/include/rules.mk
include $(TOPDIR)/src/include/defaults.mk
include $(TOPDIR)/src/include/workarounds.mk

LIBTARGETS=libefivar.so libefiboot.so libefisec.so
STATICLIBTARGETS=libefivar.a libefiboot.a libefisec.a
Expand All @@ -30,7 +29,7 @@ EFISECDB_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(EFISECDB_SOURCES)))
GENERATED_SOURCES = include/efivar/efivar-guids.h guid-symbols.c
MAKEGUIDS_SOURCES = makeguids.c util-makeguids.c
MAKEGUIDS_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(MAKEGUIDS_SOURCES)))
MAKEGUIDS_OUTPUT = $(GENERATED_SOURCES) guids.lds
MAKEGUIDS_OUTPUT = $(GENERATED_SOURCES)

util-makeguids.c : util.c
cp util.c util-makeguids.c
Expand Down Expand Up @@ -84,7 +83,7 @@ $(MAKEGUIDS_OUTPUT) : guids.txt
if [ "$${missing}" != "no" ]; then \
exit 1 ; \
fi
./makeguids $(LD_DASH_T) guids.txt guid-symbols.c include/efivar/efivar-guids.h guids.lds
./makeguids guids.txt guid-symbols.c include/efivar/efivar-guids.h

prep : makeguids $(GENERATED_SOURCES)

Expand All @@ -96,7 +95,6 @@ libefivar.a : $(patsubst %.o,%.static.o,$(LIBEFIVAR_OBJECTS))
libefivar.so : $(LIBEFIVAR_OBJECTS)
libefivar.so : | $(GENERATED_SOURCES) libefivar.map
libefivar.so : LIBS=dl
libefivar.so : LDSCRIPTS=guids.lds
libefivar.so : MAP=libefivar.map

efivar : $(EFIVAR_OBJECTS) | libefivar.so
Expand Down Expand Up @@ -137,7 +135,6 @@ deps : $(ALL_SOURCES)
clean :
@rm -rfv *~ *.o *.a *.E *.so *.so.* *.pc *.bin .*.d *.map \
makeguids guid-symbols.c include/efivar/efivar-guids.h \
guids.lds \
$(TARGETS) $(STATICTARGETS)
@# remove the deps files we used to create, as well.
@rm -rfv .*.P .*.h.P *.S.P include/efivar/.*.h.P
Expand Down
5 changes: 1 addition & 4 deletions src/include/rules.mk
Expand Up @@ -3,7 +3,6 @@ default : all
.PHONY: default all clean install test

include $(TOPDIR)/src/include/version.mk
include $(TOPDIR)/src/include/workarounds.mk

comma:= ,
empty:=
Expand Down Expand Up @@ -36,9 +35,7 @@ family = $(foreach FAMILY_SUFFIX,$(FAMILY_SUFFIXES),$($(1)_$(FAMILY_SUFFIX)))
$(CCLD) $(CCLDFLAGS) $(CPPFLAGS) -o $@ $(sort $^) $(LDLIBS)

%.so :
$(CCLD) $(CCLDFLAGS) $(CPPFLAGS) $(SOFLAGS) \
$(foreach LDS,$(LDSCRIPTS),$(LD_DASH_T) $(LDS)) \
-o $@ $^ $(LDLIBS)
$(CCLD) $(CCLDFLAGS) $(CPPFLAGS) $(SOFLAGS) -o $@ $^ $(LDLIBS)
ln -vfs $@ $@.1

%.abixml : %.so
Expand Down
24 changes: 0 additions & 24 deletions src/include/workarounds.mk

This file was deleted.

72 changes: 24 additions & 48 deletions src/makeguids.c
Expand Up @@ -107,51 +107,46 @@ write_guidnames(FILE *out, const char *listname,
gn->symbol, gn->name, gn->description);
}
fprintf(out, "};\n");
fprintf(out, "const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\t* const %s = %s_;\n", listname, listname);
fprintf(out, "const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\t* const %s_end = %s_\n\t+ %zd;\n",
listname, listname, n - 1);
}

int
main(int argc, char *argv[])
{
int rc;
int argstart = 0;
FILE *symout, *header, *ldsout;
int dash_t = 0;
FILE *symout, *header;

if (argc < 5) {
if (argc < 4) {
errx(1, "Not enough arguments.\n");
} else if (argc > 5 && !strcmp(argv[1],"-T")) {
argstart = 1;
dash_t = 1;
} else if (argc > 5) {
} else if (argc > 4) {
errx(1, "Too many arguments.\n");
}

symout = fopen(argv[argstart + 2], "w");
symout = fopen(argv[2], "w");
if (symout == NULL)
err(1, "could not open \"%s\"", argv[argstart + 2]);
rc = chmod(argv[argstart + 2], 0644);
err(1, "could not open \"%s\"", argv[2]);
rc = chmod(argv[2], 0644);
if (rc < 0)
warn("chmod(%s, 0644)", argv[argstart + 2]);
warn("chmod(%s, 0644)", argv[2]);

header = fopen(argv[argstart + 3], "w");
header = fopen(argv[3], "w");
if (header == NULL)
err(1, "could not open \"%s\"", argv[argstart + 3]);
rc = chmod(argv[argstart + 3], 0644);
if (rc < 0)
warn("chmod(%s, 0644)", argv[argstart + 3]);

ldsout = fopen(argv[argstart + 4], "w");
if (ldsout == NULL)
err(1, "could not open \"%s\"", argv[argstart + 4]);
rc = chmod(argv[argstart + 4], 0644);
err(1, "could not open \"%s\"", argv[3]);
rc = chmod(argv[3], 0644);
if (rc < 0)
warn("chmod(%s, 0644)", argv[argstart + 4]);
warn("chmod(%s, 0644)", argv[3]);

struct guidname_index *guidnames = NULL;

rc = read_guids_at(AT_FDCWD, argv[argstart + 1], &guidnames);
rc = read_guids_at(AT_FDCWD, argv[1], &guidnames);
if (rc < 0)
err(1, "could not read \"%s\"", argv[argstart + 1]);
err(1, "could not read \"%s\"", argv[1]);

struct efivar_guidname *outbuf;

Expand Down Expand Up @@ -243,25 +238,23 @@ struct efivar_guidname {\n\
fprintf(header,
"extern const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\tefi_well_known_guids[%d];\n",
i);
"\t* const efi_well_known_guids;\n");
fprintf(header,
"extern const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\tefi_well_known_guids_end;\n");
"\t* const efi_well_known_guids_end;\n");
fprintf(header,
"extern const uint64_t\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\tefi_n_well_known_guids;\n\n");
fprintf(header,
"extern const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\tefi_well_known_names[%d];\n",
i);
"\t* const efi_well_known_names;\n");
fprintf(header,
"extern const struct efivar_guidname\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
"\tefi_well_known_names_end;\n");
"\t* const efi_well_known_names_end;\n");
fprintf(header,
"extern const uint64_t\n"
"\t__attribute__((__visibility__ (\"default\")))\n"
Expand Down Expand Up @@ -310,23 +303,6 @@ struct efivar_guidname {\n\

fclose(symout);

fprintf(ldsout,
"SECTIONS\n"
"{\n"
" .data :\n"
" {\n"
" efi_well_known_guids = efi_well_known_guids_;\n"
" efi_well_known_guids_end = efi_well_known_guids_ + %zd;\n"
" efi_well_known_names = efi_well_known_names_;\n"
" efi_well_known_names_end = efi_well_known_names_ + %zd;\n"
" }\n"
"}%s;\n",
(line - 1) * sizeof(struct efivar_guidname),
(line - 1) * sizeof(struct efivar_guidname),
dash_t ? " INSERT AFTER .data" : "");

fclose(ldsout);

free(guidnames->strtab);
free(guidnames);

Expand Down

0 comments on commit cfd686d

Please sign in to comment.