Add prebuilt ABI checker support to soong

This commit adds prebuilt ABI checker support to soong so that
`cc_prebuilt_library_shared` and `cc_prebuilt_binary` are checked.

To opt out the check, add `check_elf_files: false` to your module.

Bug: 119086738
Test: lunch aosp_sailfish-userdebug && CHECK_ELF_FILES=true make check-elf-files
Change-Id: Idb4290c8f48aad545894a7ae718a537cbf832233
diff --git a/android/variable.go b/android/variable.go
index 8333635..6cf28ad 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -195,6 +195,8 @@
 	Arc                              *bool `json:",omitempty"`
 	MinimizeJavaDebugInfo            *bool `json:",omitempty"`
 
+	Check_elf_files *bool `json:",omitempty"`
+
 	UncompressPrivAppDex             *bool    `json:",omitempty"`
 	ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
 
diff --git a/cc/androidmk.go b/cc/androidmk.go
index fa0017d..0e4245e 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -362,3 +362,40 @@
 		fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
 	})
 }
+
+func (p *prebuiltLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+		if p.properties.Check_elf_files != nil {
+			fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES :=", *p.properties.Check_elf_files)
+		} else {
+			// soong_cc_prebuilt.mk does not include check_elf_file.mk by default
+			// because cc_library_shared and cc_binary use soong_cc_prebuilt.mk as well.
+			// In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to
+			// true if `p.properties.Check_elf_files` is not specified.
+			fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES := true")
+		}
+	})
+}
+
+func (p *prebuiltLibraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+	ctx.subAndroidMk(ret, p.libraryDecorator)
+	if p.shared() {
+		ctx.subAndroidMk(ret, &p.prebuiltLinker)
+		androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret)
+	}
+}
+
+func (p *prebuiltBinaryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+	ctx.subAndroidMk(ret, p.binaryDecorator)
+	ctx.subAndroidMk(ret, &p.prebuiltLinker)
+	androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret)
+}
+
+func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, ret *android.AndroidMkData) {
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+		allow := linker.Properties.Allow_undefined_symbols
+		if allow != nil {
+			fmt.Fprintln(w, "LOCAL_ALLOW_UNDEFINED_SYMBOLS :=", *allow)
+		}
+	})
+}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index ffeeb69..4446ab3 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -31,8 +31,13 @@
 
 type prebuiltLinker struct {
 	android.Prebuilt
+
 	properties struct {
 		Srcs []string `android:"arch_variant"`
+
+		// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined
+		// symbols, etc), default true.
+		Check_elf_files *bool
 	}
 }
 
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 2d7274d..74f7f27 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -60,6 +60,10 @@
 
 	// Prebuilt files for each arch.
 	Srcs []string `android:"arch_variant"`
+
+	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
+	// etc).
+	Check_elf_files *bool
 }
 
 type vndkPrebuiltLibraryDecorator struct {
@@ -155,6 +159,8 @@
 		libraryDecorator: library,
 	}
 
+	prebuilt.properties.Check_elf_files = BoolPtr(false)
+
 	module.compiler = nil
 	module.linker = prebuilt
 	module.installer = prebuilt