Browse Source

dasm-tigcc: fix segmentation faults upon accesses out of the bounds of the ROM call info table.

git-svn-id: file:///var/svn/tigccpp/trunk@1353 9552661e-59e3-4036-b4f2-dbe53926924f
debrouxl 15 years ago
parent
commit
e905a0e92d
3 changed files with 38 additions and 4 deletions
  1. 5 0
      external/dasm-tigcc/ChangeLog
  2. 10 2
      external/dasm-tigcc/m68k-dis.c
  3. 23 2
      external/dasm-tigcc/romcalls.c

+ 5 - 0
external/dasm-tigcc/ChangeLog

@@ -1,3 +1,8 @@
+2009-07-14  Lionel Debroux <lionel_debroux@yahoo.fr>
+
+        * romcalls.c: protect against accesses out of the bounds of the ROM_CALL info table.
+        * m68k-dis.c: don't output the NULL string that might be returned by romcalls_get_name().
+
 2007-06-18  Kevin Kofler  <Kevin@tigcc.ticalc.org>
 
         * generic.h (ATTRIBUTE_PACKED, ATTRIBUTE_MAY_ALIAS): fix inverted #ifdef __GNUC__ logic

+ 10 - 2
external/dasm-tigcc/m68k-dis.c

@@ -1423,7 +1423,11 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
                 pm = NEXTUWORD(buffer);
                 info->fprintf_func (info->stream, ".word 0xfff2,0x%04x", pm/4);
                 if (romcalls_is_loaded())
-                  info->fprintf_func (info->stream, " /*%s*/", romcalls_get_name(pm / 4));
+                  {
+                      const char * rc_name = romcalls_get_name(pm / 4);
+                      if (rc_name != NULL)
+                        info->fprintf_func (info->stream, " /*%s*/", rc_name);
+                  }
                 return 4;
               case 0xffee:  /* jmp __ld_entry_point_plus_0x8000+word */
                 pm = NEXTWORD(buffer);
@@ -1452,7 +1456,11 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
               default:  /* 2 byte ROM CALL */
                 info->fprintf_func (info->stream, ".word 0xf800+0x%x", op & 0x7ff);
                 if (romcalls_is_loaded())
-                  info->fprintf_func (info->stream, " /*%s*/", romcalls_get_name(op & 0x7ff));
+                  {
+                    const char * rc_name = romcalls_get_name(op & 0x7ff);
+                    if (rc_name != NULL)
+                      info->fprintf_func (info->stream, " /*%s*/", rc_name);
+                  }
                 return 2;
             }
         }

+ 23 - 2
external/dasm-tigcc/romcalls.c

@@ -68,6 +68,12 @@ void romcalls_get_table_infos(uint32_t *base, uint32_t *size)
 
 	*base = rd_long(&rom[0x12000 + 0x88 + 0xC8]);
 	*size = rd_long(&rom[((*base-4) & 0x0fffff)]);
+
+	if (*size > sizeof(table)/sizeof(table[0]))
+	{
+		fprintf(stderr,"WARNING: this ROM_CALL table has more entries than those of all known AMS versions !\nWARNING: clamping the number of entries.\n");
+		*size = sizeof(table)/sizeof(table[0]);
+	}
 }
 
 /*
@@ -157,10 +163,25 @@ int romcalls_is_addr(uint32_t addr)
 
 const char* romcalls_get_name(int id)
 {
-	if(!loaded)	return "not loaded";
-	return table[id].name;
+	int maxid = size;
+	if (!loaded)	return "not loaded";
+	if (id >= 0)
+	{
+		// Assume maximum number of ROM_CALLs if we're not disassembling an OS.
+		if (maxid == 0)
+		{
+			maxid = sizeof(table)/sizeof(table[0]);
+		}
+		if (id < maxid)
+		{
+			return table[id].name;
+		}
+	}
+	return NULL;
 }
 
+// No need to check the parameter: the only caller of romcalls_get_addr() calls
+// romcalls_get_table_infos() before calling romcalls_get_addr().
 uint32_t romcalls_get_addr(int id)
 {
 	return table[id].addr;