ovl_offset: use elf symbols instead of refmap

add a plugin_ram_end symbol to plugin.lds and rewrite ovl_offset.pl
to read plugin_ram_end and plugin_load_end_addr from the elf via nm.
this removes all dependence on the linker map file format, which
differs between gnu ld and lld.

Change-Id: I66e623d9a2b44eb84ae7035155c84d8afe46df23
This commit is contained in:
mojyack 2026-04-21 13:31:43 +09:00
parent 018994e8c7
commit e62ac0d2c6
11 changed files with 39 additions and 32 deletions

View file

@ -32,7 +32,7 @@ $(CHESSBOX_OBJDIR)/chessbox.refmap: $(CHESSBOX_OBJ)
$(CHESSBOX_OUTLDS): $(PLUGIN_LDS) $(CHESSBOX_OBJDIR)/chessbox.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(CHESSBOX_OBJDIR)/chessbox.refmap))
$(TOOLSDIR)/ovl_offset.pl $(CHESSBOX_OBJDIR)/chessbox.refelf))
$(CHESSBOX_OBJDIR)/chessbox.ovl: $(CHESSBOX_OBJ) $(CHESSBOX_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -29,7 +29,7 @@ $(GOBAN_BUILDDIR)/goban.refmap: $(GOBAN_OBJ)
$(GOBAN_OUTLDS): $(PLUGIN_LDS) $(GOBAN_BUILDDIR)/goban.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(GOBAN_BUILDDIR)/goban.refmap))
$(TOOLSDIR)/ovl_offset.pl $(GOBAN_BUILDDIR)/goban.refelf))
$(GOBAN_BUILDDIR)/goban.ovl: $(GOBAN_OBJ) $(GOBAN_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -44,11 +44,11 @@ $(IMGVBUILDDIR)/%.ovl: $(IMGDEC_OUTLDS)
# rule to create reference map for image decoder
$(IMGVBUILDDIR)/%.refmap: $(APPSDIR)/plugin.h $(IMGVSRCDIR)/imageviewer.h $(PLUGINLINK_LDS) $(PLUGIN_LIBS)
$(call PRINTS,LD $(@F))$(CC) $(IMGDECFLAGS) -o /dev/null \
$(call PRINTS,LD $(@F))$(CC) $(IMGDECFLAGS) -o $(IMGVBUILDDIR)/$*.refelf \
$(filter %.o, $^) \
$(filter %.a, $+) \
-lgcc $(IMGDECLDFLAGS)
$(IMGVBUILDDIR)/%.link: $(PLUGIN_LDS) $(IMGVBUILDDIR)/%.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DIMGVDECODER_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(IMGVBUILDDIR)/$*.refmap))
$(TOOLSDIR)/ovl_offset.pl $(IMGVBUILDDIR)/$*.refelf))

View file

@ -66,7 +66,7 @@ $(LUA_BUILDDIR)/lua.refmap: $(LUA_OBJ) $(TLSFLIB)
$(LUA_OUTLDS): $(PLUGIN_LDS) $(LUA_BUILDDIR)/lua.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(LUA_BUILDDIR)/lua.refmap))
$(TOOLSDIR)/ovl_offset.pl $(LUA_BUILDDIR)/lua.refelf))
$(LUA_BUILDDIR)/lua.ovl: $(LUA_OBJ) $(TLSFLIB) $(LUA_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -30,7 +30,7 @@ $(PICTUREFLOW_OBJDIR)/pictureflow.refmap: $(PICTUREFLOW_OBJ)
$(PICTUREFLOW_OUTLDS): $(PLUGIN_LDS) $(PICTUREFLOW_OBJDIR)/pictureflow.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(PICTUREFLOW_OBJDIR)/pictureflow.refmap))
$(TOOLSDIR)/ovl_offset.pl $(PICTUREFLOW_OBJDIR)/pictureflow.refelf))
$(PICTUREFLOW_OBJDIR)/pictureflow.ovl: $(PICTUREFLOW_OBJ) $(PICTUREFLOW_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -310,6 +310,9 @@ SECTIONS
plugin_load_end_addr = .;
}
_plugin_ram_end = ORIGIN(PLUGIN_RAM) + LENGTH(PLUGIN_RAM);
plugin_ram_end = ORIGIN(PLUGIN_RAM) + LENGTH(PLUGIN_RAM);
/* Special trick to avoid a linker error when no other sections are
left after garbage collection (plugin not for this platform) */
.comment 0 :

View file

@ -183,7 +183,7 @@ $(BUILDDIR)/apps/plugins/%.lua: $(ROOTDIR)/apps/plugins/%.lua
$(call PRINTS,CP $(subst $(ROOTDIR)/,,$<))cp $< $(BUILDDIR)/apps/plugins/
$(BUILDDIR)/%.refmap: $(APPSDIR)/plugin.h $(OVERLAYREF_LDS) $(PLUGIN_LIBS) $(PLUGIN_CRT0)
$(call PRINTS,LD $(@F))$(CC) $(PLUGINFLAGS) -o /dev/null \
$(call PRINTS,LD $(@F))$(CC) $(PLUGINFLAGS) -o $(basename $@).refelf \
$(filter %.o, $^) \
$(filter %.a, $+) \
-lgcc $(OVERLAYLDFLAGS)

View file

@ -30,7 +30,7 @@ $(ROCKBOY_OBJDIR)/rockboy.refmap: $(ROCKBOY_OBJ)
$(ROCKBOY_OUTLDS): $(PLUGIN_LDS) $(ROCKBOY_OBJDIR)/rockboy.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(ROCKBOY_OBJDIR)/rockboy.refmap))
$(TOOLSDIR)/ovl_offset.pl $(ROCKBOY_OBJDIR)/rockboy.refelf))
$(ROCKBOY_OBJDIR)/rockboy.ovl: $(ROCKBOY_OBJ) $(ROCKBOY_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -71,7 +71,7 @@ $(SDL_OBJDIR)/duke3d.refmap: $(SDL_OBJ) $(DUKE3D_OBJ) $(TLSFLIB)
$(DUKE3D_OUTLDS): $(PLUGIN_LDS) $(SDL_OBJDIR)/duke3d.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/duke3d.refmap))
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/duke3d.refelf))
$(SDL_OBJDIR)/duke3d.ovl: $(SDL_OBJ) $(DUKE3D_OBJ) $(TLSFLIB) $(DUKE3D_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \
@ -88,7 +88,7 @@ $(SDL_OBJDIR)/wolf3d.refmap: $(SDL_OBJ) $(WOLF3D_OBJ) $(TLSFLIB)
$(WOLF3D_OUTLDS): $(PLUGIN_LDS) $(SDL_OBJDIR)/wolf3d.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/wolf3d.refmap))
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/wolf3d.refelf))
$(SDL_OBJDIR)/wolf3d.ovl: $(SDL_OBJ) $(WOLF3D_OBJ) $(TLSFLIB) $(WOLF3D_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \
@ -106,7 +106,7 @@ $(SDL_OBJDIR)/quake.refmap: $(SDL_OBJ) $(QUAKE_OBJ) $(TLSFLIB)
$(QUAKE_OUTLDS): $(PLUGIN_LDS) $(SDL_OBJDIR)/quake.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/quake.refmap))
$(TOOLSDIR)/ovl_offset.pl $(SDL_OBJDIR)/quake.refelf))
$(SDL_OBJDIR)/quake.ovl: $(SDL_OBJ) $(QUAKE_OBJ) $(TLSFLIB) $(QUAKE_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -38,7 +38,7 @@ $(ZXBOX_OBJDIR)/zxbox.refmap: $(ZXBOX_OBJ)
$(ZXBOX_OUTLDS): $(PLUGIN_LDS) $(ZXBOX_OBJDIR)/zxbox.refmap
$(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DPLUGIN -DOVERLAY_OFFSET=$(shell \
$(TOOLSDIR)/ovl_offset.pl $(ZXBOX_OBJDIR)/zxbox.refmap))
$(TOOLSDIR)/ovl_offset.pl $(ZXBOX_OBJDIR)/zxbox.refelf))
$(ZXBOX_OBJDIR)/zxbox.ovl: $(ZXBOX_OBJ) $(ZXBOX_OUTLDS)
$(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \

View file

@ -1,35 +1,39 @@
#!/usr/bin/perl
# Calculate the highest possible location for an overlay based
# on a reference map file (.refmap)
# on a reference ELF file (.refelf)
# Reads plugin_load_end_addr and plugin_ram_end symbols from the ELF
# via nm, then computes the overlay offset.
sub map_scan {
sub main {
# The buflib handle table is a few hundred bytes, just before
# the plugin buffer. We assume it's never more than 1024 bytes.
# If this assumption is wrong, overlay loading will fail.
my $max_handle_table_size = 1024;
my ($map) = @_;
my $ramstart = -1, $ramsize = -1, $startaddr = -1, $endaddr = -1;
open (MAP, "<$map");
while (<MAP>) {
if ($_ =~ /^PLUGIN_RAM +0x([0-9a-f]+) +0x([0-9a-f]+)$/) {
$ramstart = hex($1);
$ramsize = hex($2);
my ($elf) = @_;
my $ram_end = -1;
my $load_end = -1;
open (NM, "nm $elf |") or die "Cannot run nm on $elf: $!\n";
while (<NM>) {
if ($_ =~ /^([0-9a-fA-F]+)\s+\S+\s+plugin_ram_end$/) {
$ram_end = hex($1);
}
elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_start_addr = ./) {
$startaddr = hex($1);
}
elsif ($_ =~ / +0x([0-9a-f]+) +_?plugin_load_end_addr = ./) {
$endaddr = hex($1);
elsif ($_ =~ /^([0-9a-fA-F]+)\s+\S+\s+plugin_load_end_addr$/) {
$load_end = hex($1);
}
}
close (MAP);
if ($ramstart < 0 || $ramsize < 0 || $startaddr < 0 || $endaddr < 0
|| $ramstart != $startaddr) {
printf "Could not analyze map file.\n";
close(NM);
if ($ram_end < 0 || $load_end < 0) {
printf STDERR "Could not read symbols from $elf\n";
printf STDERR " plugin_ram_end: %s\n", $ram_end < 0 ? "not found" : sprintf("0x%x", $ram_end);
printf STDERR " plugin_load_end_addr: %s\n", $load_end < 0 ? "not found" : sprintf("0x%x", $load_end);
exit 1;
}
return $ramstart + $ramsize - $endaddr - $max_handle_table_size;
return ($ram_end - $load_end - $max_handle_table_size) & ~0xf;
}
printf map_scan($ARGV[0]) & ~0xf;
printf main($ARGV[0]);