+ size = bfd_section_size (section);
+ if (pc >= vma + size)
+ return;
+
+ found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma,
+ &filename, &functionname,
+ &line, &discriminator);
+}
+
+/* Look for an offset in a section. This is directly called. */
+
+static void
+find_offset_in_section (bfd *abfd, asection *section)
+{
+ bfd_size_type size;
+
+ if (found)
+ return;
+
+ if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
+ return;
+
+ size = bfd_section_size (section);
+ if (pc >= size)
+ return;
+
+ found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc,
+ &filename, &functionname,
+ &line, &discriminator);
+}
+
+/* Lookup a symbol with offset in symbol table. */
+
+static bfd_vma
+lookup_symbol (bfd *abfd, char *sym, size_t offset)
+{
+ long i;
+
+ for (i = 0; i < symcount; i++)
+ {
+ if (!strcmp (syms[i]->name, sym))
+ return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
+ }
+ /* Try again mangled */
+ for (i = 0; i < symcount; i++)
+ {
+ char *d = bfd_demangle (abfd, syms[i]->name, demangle_flags);
+ bool match = d && !strcmp (d, sym);
+ free (d);
+
+ if (match)
+ return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
+ }
+ return 0;
+}
+
+/* Split an symbol+offset expression. adr is modified. */
+
+static bool
+is_symbol (char *adr, char **symp, size_t *offset)
+{
+ char *end;
+
+ while (ISSPACE (*adr))
+ adr++;
+ if (ISDIGIT (*adr) || *adr == 0)
+ return false;
+ /* Could be either symbol or hex number. Check if it has +. */
+ if (TOUPPER(*adr) >= 'A' && TOUPPER(*adr) <= 'F' && !strchr (adr, '+'))
+ return false;
+
+ *symp = adr;
+ while (*adr && !ISSPACE (*adr) && *adr != '+')
+ adr++;
+ end = adr;
+ while (ISSPACE (*adr))
+ adr++;
+ *offset = 0;
+ if (*adr == '+')
+ {
+ adr++;
+ *offset = strtoul(adr, NULL, 0);
+ }
+ *end = 0;
+ return true;