linker: simplify how warnings turn into errors past a certain api level.

This was motivated by the fact that most of the _anchors_ on the doc page were outdated. I've taken the simple expedient of removing those. I was then struck by the amount of copy & paste involved in showing both warning and error, so the new function takes care of that.

Change-Id: I82d3e6a6d8235a78f7cfe427b1209a1f9c83f682
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 0b829b3..c42712a 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1084,19 +1084,16 @@
 
 const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
 #if !defined(__LP64__)
-  // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
-  int app_target_api_level = get_application_target_sdk_version();
-  if (app_target_api_level < 23) {
+  if (get_application_target_sdk_version() < 23) {
     const char* bname = basename(dt_needed);
     if (bname != dt_needed) {
-      DL_WARN_documented_change(23,
-                                "invalid-dt_needed-entries-enforced-for-api-level-23",
-                                "library \"%s\" has invalid DT_NEEDED entry \"%s\"",
-                                sopath, dt_needed, app_target_api_level);
-      add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
+      // Work around incorrect DT_NEEDED entries for old apps: http://b/21364029
+      if (!DL_ERROR_AFTER(23, "library \"%s\" has invalid DT_NEEDED entry \"%s\"",
+                          sopath, dt_needed)) {
+        add_dlwarning(sopath, "invalid DT_NEEDED entry",  dt_needed);
+        return bname;
+      }
     }
-
-    return bname;
   }
 #endif
   return dt_needed;
@@ -1236,11 +1233,12 @@
         const soinfo* needed_or_dlopened_by = task->get_needed_by();
         const char* sopath = needed_or_dlopened_by == nullptr ? "(unknown)" :
                                                       needed_or_dlopened_by->get_realpath();
-        DL_WARN_documented_change(24,
-                                  "private-api-enforced-for-api-level-24",
-                                  "library \"%s\" (\"%s\") needed or dlopened by \"%s\" "
-                                  "is not accessible by namespace \"%s\"",
-                                  name, realpath.c_str(), sopath, ns->get_name());
+        // is_exempt_lib() always returns true for api levels < 24,
+        // so no need to check the return value of DL_ERROR_AFTER().
+        // We still call it rather than DL_WARN() to get the extra clarification.
+        DL_ERROR_AFTER(24, "library \"%s\" (\"%s\") needed or dlopened by \"%s\" "
+                       "is not accessible by namespace \"%s\"",
+                       name, realpath.c_str(), sopath, ns->get_name());
         add_dlwarning(sopath, "unauthorized access to",  name);
       }
     } else {
@@ -3327,19 +3325,19 @@
     }
   }
 
-  // Before M release, linker was using basename in place of soname. In the case when DT_SONAME is
-  // absent some apps stop working because they can't find DT_NEEDED library by soname. This
-  // workaround should keep them working. (Applies only for apps targeting sdk version < M.) Make
-  // an exception for the main executable, which does not need to have DT_SONAME. The linker has an
-  // DT_SONAME but the soname_ field is initialized later on.
+  // Before API 23, the linker used the basename in place of DT_SONAME.
+  // After we switched, apps with libraries without a DT_SONAME stopped working:
+  // they could no longer be found by DT_NEEDED from another library.
+  // The main executable does not need to have a DT_SONAME.
+  // The linker has a DT_SONAME, but the soname_ field is initialized later on.
   if (soname_.empty() && this != solist_get_somain() && !relocating_linker &&
       get_application_target_sdk_version() < 23) {
     soname_ = basename(realpath_.c_str());
-    DL_WARN_documented_change(23, "missing-soname-enforced-for-api-level-23",
-                              "\"%s\" has no DT_SONAME (will use %s instead)", get_realpath(),
-                              soname_.c_str());
-
-    // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
+    // The `if` above means we don't get here for api levels >= 23,
+    // so no need to check the return value of DL_ERROR_AFTER().
+    // We still call it rather than DL_WARN() to get the extra clarification.
+    DL_ERROR_AFTER(23, "\"%s\" has no DT_SONAME (will use %s instead)",
+                   get_realpath(), soname_.c_str());
   }
 
   // Validate each library's verdef section once, so we don't have to validate
@@ -3385,20 +3383,12 @@
 
 #if !defined(__LP64__)
   if (has_text_relocations) {
-    // Fail if app is targeting M or above.
-    int app_target_api_level = get_application_target_sdk_version();
-    if (app_target_api_level >= 23) {
-      DL_ERR_AND_LOG("\"%s\" has text relocations (%s#Text-Relocations-Enforced-for-API-level-23)",
-                     get_realpath(), kBionicChangesUrl);
+    if (DL_ERROR_AFTER(23, "\"%s\" has text relocations", get_realpath())) {
       return false;
     }
+    add_dlwarning(get_realpath(), "text relocations");
     // Make segments writable to allow text relocations to work properly. We will later call
     // phdr_table_protect_segments() after all of them are applied.
-    DL_WARN_documented_change(23,
-                              "Text-Relocations-Enforced-for-API-level-23",
-                              "\"%s\" has text relocations",
-                              get_realpath());
-    add_dlwarning(get_realpath(), "text relocations");
     if (phdr_table_unprotect_segments(phdr, phnum, load_bias, should_pad_segments_,
                                       should_use_16kib_app_compat_) < 0) {
       DL_ERR("can't unprotect loadable segments for \"%s\": %m", get_realpath());